library(readxl)
library(clusterProfiler)
clusterProfiler v4.8.2  For help: https://yulab-smu.top/biomedical-knowledge-mining-book/

If you use clusterProfiler in published research, please cite:
T Wu, E Hu, S Xu, M Chen, P Guo, Z Dai, T Feng, L Zhou, W Tang, L Zhan, X Fu, S Liu, X Bo, and G Yu. clusterProfiler 4.0: A universal enrichment tool for interpreting omics data. The Innovation. 2021, 2(3):100141

Attaching package: ‘clusterProfiler’

The following object is masked from ‘package:biomaRt’:

    select

The following object is masked from ‘package:IRanges’:

    slice

The following object is masked from ‘package:S4Vectors’:

    rename

The following object is masked from ‘package:stats’:

    filter
library(GOplot)
Loading required package: ggplot2
Loading required package: ggdendro
Loading required package: gridExtra

Attaching package: ‘gridExtra’

The following object is masked from ‘package:Biobase’:

    combine

The following object is masked from ‘package:BiocGenerics’:

    combine

Loading required package: RColorBrewer
library(DOSE)
DOSE v3.26.1  For help: https://yulab-smu.top/biomedical-knowledge-mining-book/

If you use DOSE in published research, please cite:
Guangchuang Yu, Li-Gen Wang, Guang-Rong Yan, Qing-Yu He. DOSE: an R/Bioconductor package for Disease Ontology Semantic and Enrichment analysis. Bioinformatics 2015, 31(4):608-609
library(topGO)
Loading required package: graph
Loading required package: GO.db
Loading required package: AnnotationDbi

Attaching package: ‘AnnotationDbi’

The following object is masked from ‘package:clusterProfiler’:

    select

Loading required package: SparseM

Attaching package: ‘SparseM’

The following object is masked from ‘package:base’:

    backsolve


groupGOTerms:   GOBPTerm, GOMFTerm, GOCCTerm environments built.

Attaching package: ‘topGO’

The following object is masked from ‘package:IRanges’:

    members
library(circlize)
========================================
circlize version 0.4.15
CRAN page: https://cran.r-project.org/package=circlize
Github page: https://github.com/jokergoo/circlize
Documentation: https://jokergoo.github.io/circlize_book/book/

If you use it in published research, please cite:
Gu, Z. circlize implements and enhances circular visualization
  in R. Bioinformatics 2014.

This message can be suppressed by:
  suppressPackageStartupMessages(library(circlize))
========================================


Attaching package: ‘circlize’

The following object is masked from ‘package:graph’:

    degree
library("pheatmap")

library("ggsci")
library("ggplot2")
library("gridExtra")

library("survival")
library("survminer")
Loading required package: ggpubr

Attaching package: ‘survminer’

The following object is masked from ‘package:survival’:

    myeloma
library(ggpubr)
library(rstpm2)
library(corrplot)
corrplot 0.92 loaded
library(Hmisc)
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio

Attaching package: ‘Hmisc’

The following object is masked from ‘package:AnnotationDbi’:

    contents

The following object is masked from ‘package:ggdendro’:

    label

The following object is masked from ‘package:Biobase’:

    contents

The following objects are masked from ‘package:base’:

    format.pval, units
library(cowplot)

Attaching package: ‘cowplot’

The following object is masked from ‘package:ggpubr’:

    get_legend
library(reshape)

Attaching package: ‘reshape’

The following object is masked from ‘package:cowplot’:

    stamp

The following object is masked from ‘package:clusterProfiler’:

    rename

The following objects are masked from ‘package:S4Vectors’:

    expand, rename
library(ggbreak)
ggbreak v0.1.2

If you use ggbreak in published research, please cite the following paper:

S Xu, M Chen, T Feng, L Zhan, L Zhou, G Yu. Use ggbreak to effectively utilize plotting space to deal with large datasets and outliers.
Frontiers in Genetics. 2021, 12:774846. doi: 10.3389/fgene.2021.774846 
library(ggrepel)
GiniClin <- read_excel("~/Project/TCR_Summary/Writing/SumSup.xlsx", sheet = "Gini_Clinic")

GiniClin <- as.data.frame(GiniClin, row.names = GiniClin$ID)

Figure 1

f1a <- ggplot(GiniClin, aes(x=GiniIndex)) +
  geom_histogram(colour = "black", fill="#4dbbd5ff", bins = 50) +
  theme_classic() +
  theme(axis.text = element_text(size = 20)) +
  labs(title = "Gini_distribution", y = "Patient count") +
  scale_x_continuous(expand = c(0,0), limits = c(0, 0.8)) + scale_y_continuous(expand = c(0,0), limits = c(0,25))

f1a
Warning: Removed 2 rows containing missing values (geom_bar).

qqnorm(GiniClin_tumor$GiniIndex, ylab = 'GiniIndex')
qqline(GiniClin_tumor$GiniIndex) # 增加趋势直线,利于比较

# H0 is that the data fit normal distribution
shapiro.test(GiniClin_tumor$GiniIndex)

    Shapiro-Wilk normality test

data:  GiniClin_tumor$GiniIndex
W = 0.92421, p-value = 4.017e-08
GiniClin_AcSq <- GiniClin[GiniClin$histology_Hans_B_WHO_2015 %in% c("AC","SqCC"), ]

f1a_2 <- ggplot(GiniClin_AcSq, aes(x=GiniIndex, fill = histology_Hans_B_WHO_2015)) +
  geom_histogram(color = "black", position = "identity", bins = 50, size = 0.3) +
  theme_classic() +
  theme(axis.text = element_text(size = 20, colour = "black"), legend.position = c(0.8,0.8)) +
  labs(title = "Gini_distribution", fill = "Histology") +
  scale_fill_manual(values = alpha(c("#F8766D", "#00BFC4"), 0.75)) +
  scale_x_continuous(expand = c(0,0), limits = c(0,0.85)) + scale_y_continuous(expand = c(0,0), limits = c(0,17), breaks = c(seq(0,15,5)))

f1a_2
Warning: Removed 4 rows containing missing values (geom_bar).

GiniClin_tumor <- read_excel("~/Project/TCR_Summary/Writing/SumSup.xlsx", sheet = "Gini_Clinic_tumor")

GiniClin_tumor <- as.data.frame(GiniClin_tumor, row.names = GiniClin_tumor$ID)

Box plot

# histology
f1b_3 <- ggplot(GiniClin_tumor, aes(x = histology_Hans_B_WHO_2015, y = GiniIndex, fill=histology_Hans_B_WHO_2015)) +
  geom_boxplot(outlier.colour = "black", outlier.shape = 16, outlier.size = 2, colour = "black") +
  theme_classic() +
  #coord_flip() +
  scale_fill_manual(values = c("#F8766D", "#999999", "#00BF7D","#00B0F6","#A3A500", "#00BFC4")) +
  labs(title = "Histology", x = "Histology") +
  theme(legend.position = "none",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20)) +
  stat_compare_means(paired = NULL)

f1b_3

GiniClin_tumor[GiniClin_tumor$gender == "M" ,"gender"] <- "Male"
GiniClin_tumor[GiniClin_tumor$gender == "F" ,"gender"] <- "Female"

f1b_4 <- ggplot(GiniClin_tumor, aes(x = gender, y = GiniIndex, fill=gender)) +
  geom_boxplot(outlier.colour = "black", outlier.shape = 16, outlier.size = 2, colour = "black") +
  theme_classic() +
  # coord_flip() +
  # scale_fill_npg() +
  labs(title = "Gender", x = "Sex") +
  theme(legend.position = "none",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20)) +
  stat_compare_means(paired = NULL)

f1b_4

# WHO PS
GiniClin_tumor[GiniClin_tumor$WHO_PS == 0 ,"WHO_PS_group"] <- 0
GiniClin_tumor[GiniClin_tumor$WHO_PS > 0 ,"WHO_PS_group"] <- "> 0"

f1b_6 <- ggplot(GiniClin_tumor, aes(x = WHO_PS_group, y = GiniIndex, fill=WHO_PS_group)) +
  geom_boxplot(outlier.colour = "black", outlier.shape = 16, outlier.size = 2, colour = "black") +
  theme_classic() +
  # coord_flip() +
  scale_fill_manual(values = c("#F8766D", "#00BFC4")) +
  labs(title = "WHO performance status", x = "WHO performance rank") +
  theme(legend.position = "none",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20)) +
  stat_compare_means(paired = FALSE)

f1b_6

AC/SqCC

ggplot(GiniClin_tumor[GiniClin_tumor$histology_Hans_B_WHO_2015 == "AC", ], aes(x = stageGroup, y = GiniIndex, fill=stageGroup)) +
  geom_boxplot(outlier.colour = "black", outlier.shape = 16, outlier.size = 2, colour = "black") +
  theme_classic() +
  # coord_flip() +
  # scale_color_npg() +
  labs(title = "Stage", x = "Stage") +
  theme(legend.position = "none",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20)) +
  stat_compare_means(paired = NULL)

ggplot(GiniClin_tumor[GiniClin_tumor$histology_Hans_B_WHO_2015 == "SqCC", ], aes(x = stageGroup, y = GiniIndex, fill=stageGroup)) +
  geom_boxplot(outlier.colour = "black", outlier.shape = 16, outlier.size = 2, colour = "black") +
  theme_classic() +
  # coord_flip() +
  # scale_color_npg() +
  labs(title = "Stage", x = "Stage") +
  theme(legend.position = "none",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20)) +
  stat_compare_means(paired = NULL)

ggplot(GiniClin_tumor[GiniClin_tumor$histology_Hans_B_WHO_2015 == "AC", ], aes(x = WHO_PS_group, y = GiniIndex, fill=WHO_PS_group)) +
  geom_boxplot(outlier.colour = "black", outlier.shape = 16, outlier.size = 2, colour = "black") +
  theme_classic() +
  # coord_flip() +
  scale_fill_manual(values = c("#F8766D", "#00BFC4")) +
  labs(title = "WHO performance status", x = "WHO performance rank") +
  theme(legend.position = "none",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20)) +
  stat_compare_means(paired = FALSE)

ggplot(GiniClin_tumor[GiniClin_tumor$histology_Hans_B_WHO_2015 == "SqCC", ], aes(x = WHO_PS_group, y = GiniIndex, fill=WHO_PS_group)) +
  geom_boxplot(outlier.colour = "black", outlier.shape = 16, outlier.size = 2, colour = "black") +
  theme_classic() +
  # coord_flip() +
  scale_fill_manual(values = c("#F8766D", "#00BFC4")) +
  labs(title = "WHO performance status", x = "WHO performance rank") +
  theme(legend.position = "none",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20)) +
  stat_compare_means(paired = FALSE)

Figure 2

library("survival")
library("survminer")

Attaching package: ‘survminer’

The following object is masked from ‘package:survival’:

    myeloma

Figure2A: KM plot

All patient

GiniClin_tumor[GiniClin_tumor$GiniIndex >= 0.25431, "giniGroup"] <- "Above median"
GiniClin_tumor[GiniClin_tumor$GiniIndex < 0.25431, "giniGroup"] <- "Under median"
GiniClin_tumor$giniGroup = factor(GiniClin_tumor$giniGroup, levels = c("Above median", "Under median"))
# construct the object
fig2test <- survfit(Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ giniGroup, data = GiniClin_tumor)

print(fig2test)
Call: survfit(formula = Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ 
    giniGroup, data = GiniClin_tumor)

                        n events median 0.95LCL 0.95UCL
giniGroup=Under median 91     46   4.99    3.55      NA
giniGroup=Above median 91     40     NA    4.80      NA
summary(fig2test)$table
                       records n.max n.start events    rmean se(rmean)   median  0.95LCL 0.95UCL
giniGroup=Under median      91    91      91     46 3.746049 0.1583925 4.985626 3.545517      NA
giniGroup=Above median      91    91      91     40 3.680266 0.1885308       NA 4.799452      NA
fig2a_all
Warning messages:
1: In overlay(...) :
  reverting 'unnamed.chunk.label' to 'unnamed-chunk' for duration of render
2: In overlay(...) :
  reverting 'unnamed.chunk.label' to 'unnamed-chunk' for duration of render
3: In overlay(...) :
  reverting 'unnamed.chunk.label' to 'unnamed-chunk' for duration of render

fig2a_continue.cox <- coxph(Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ GiniIndex, data = GiniClin_tumor)
fig2a_continue.cox
Call:
coxph(formula = Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ 
    GiniIndex, data = GiniClin_tumor)

             coef exp(coef) se(coef)      z     p
GiniIndex -0.5778    0.5611   1.0416 -0.555 0.579

Likelihood ratio test=0.31  on 1 df, p=0.5749
n= 182, number of events= 86 
ggsurvplot(survfit(fig2a_continue.cox, data=GiniClin_tumor), color = "#2E9FDF",ggtheme = theme_minimal())
Warning: Now, to change color palette, use the argument palette= '#2E9FDF' instead of color = '#2E9FDF'

Time split surv

fig2_timespl.cox <- coxph(Surv(tstart, OS_years_5_years_trunk_20190329, event==1) ~ giniGroup_nr:strata(tgroup), data=fig2_timespl, ties="efron")
summary(fig2_timespl.cox)
Call:
coxph(formula = Surv(tstart, OS_years_5_years_trunk_20190329, 
    event == 1) ~ giniGroup_nr:strata(tgroup), data = fig2_timespl, 
    ties = "efron")

  n= 323, number of events= 85 

                                       coef exp(coef) se(coef)      z Pr(>|z|)  
giniGroup_nr:strata(tgroup)tgroup=1  0.5457    1.7258   0.3292  1.658   0.0974 .
giniGroup_nr:strata(tgroup)tgroup=2 -0.7484    0.4731   0.3150 -2.376   0.0175 *
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

                                    exp(coef) exp(-coef) lower .95 upper .95
giniGroup_nr:strata(tgroup)tgroup=1    1.7258     0.5794    0.9052    3.2901
giniGroup_nr:strata(tgroup)tgroup=2    0.4731     2.1137    0.2552    0.8772

Concordance= 0.58  (se = 0.027 )
Likelihood ratio test= 8.86  on 2 df,   p=0.01
Wald test            = 8.39  on 2 df,   p=0.02
Score (logrank) test = 8.73  on 2 df,   p=0.01
cox.zph(fig2_timespl.cox)
                            chisq df    p
giniGroup_nr:strata(tgroup)  1.22  2 0.54
GLOBAL                       1.22  2 0.54
fig2_mod_tvc <- stpm2(Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329 == 1) ~ giniGroup_nr, data = GiniClin_tumor, df=3, tvc=list(giniGroup_nr=1))
Warning in gsm(formula = Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329 ==  :
  Some event times <= 0
plot(fig2_mod_tvc, newdata = data.frame(giniGroup_nr = 0), type = "hazard",  xlim=c(0.5,5), ylim=c(0,0.2), ylab = "Hazard", xlab = "Time", lwd = 2, ci = FALSE)
Warning in rug(eventTimes, col = line.col) :
  some values will be clipped
plot(fig2_mod_tvc, newdata = data.frame(giniGroup_nr = 1), type = "hazard", line.col=2, ci=FALSE, lwd = 2, add=TRUE)

Calculate best cutoff

fig2.cut <- surv_cutpoint(GiniClin_tumor,
                          time = "OS_years_5_years_trunk_20190329",
                          event = "status_5_years_trunk_20190329",
                          variables = "GiniIndex")
summary(fig2.cut)
plot(fig2.cut, "GiniIndex", palette = "npg")
$GiniIndex
Warning message:
In overlay(...) :
  reverting 'unnamed.chunk.label' to 'unnamed-chunk' for duration of render

Calculate AC and SqCC

plot(fig2.cut_AC, "GiniIndex", palette = "npg")
$GiniIndex

KM without censoring

fig2_NoCensor_test <- survfit(Surv(OS_years_20190329, status_out_20190329) ~ giniGroup, data = GiniClin_tumor)

print(fig2_NoCensor_test)
Call: survfit(formula = Surv(OS_years_20190329, status_out_20190329) ~ 
    giniGroup, data = GiniClin_tumor)

                        n events median 0.95LCL 0.95UCL
giniGroup=Under median 91     66   5.17    3.55    7.59
giniGroup=Above median 91     53   6.66    4.80      NA
summary(fig2_NoCensor_test)$table
                       records n.max n.start events    rmean se(rmean)   median  0.95LCL 0.95UCL
giniGroup=Under median      91    91      91     66 6.482247 0.4825654 5.169062 3.545517 7.59206
giniGroup=Above median      91    91      91     53 7.380460 0.5523298 6.661191 4.799452      NA

fig2_NoCensor.cut <- surv_cutpoint(GiniClin_tumor,
                          time = "OS_years_20190329",
                          event = "status_out_20190329",
                          variables = "GiniIndex")
summary(fig2_NoCensor.cut)
plot(fig2_NoCensor.cut, "GiniIndex", palette = "npg")
$GiniIndex

ggsurvplot(fig2_NoCensor.cut.fit,
                        pval = TRUE,
                        palette = c("#e64b35", "#4dbbd5"),
                        break.time.by = 2,
                        ggtheme = theme_classic(),
                        legend.labs = c("Above median", "Under median"),
                        risk.table = "abs_pct",
                        risk.table.y.text = FALSE,
                        xlab = "Time (years)",
                        title = "giniSurv_without_censoring",
                        axes.offset = FALSE,
                        risk.table.fontsize = 2.5,
                        legend = c(0.9,0.9),
                        risk.table.title = "Number at risk by time: n (%)",
                        font.main = c())

AC patient

GiniClin_tumor_Ac = GiniClin_tumor[GiniClin_tumor$histology_Hans_B_WHO_2015 == "AC", ]

fig2ACtest <- survfit(Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ giniGroup, data = GiniClin_tumor_Ac)

print(fig2ACtest)
Call: survfit(formula = Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ 
    giniGroup, data = GiniClin_tumor_Ac)

                        n events median 0.95LCL 0.95UCL
giniGroup=Above median 50     20     NA    4.80      NA
giniGroup=Under median 57     31   4.07    2.95      NA
print("====")
[1] "===="
summary(fig2ACtest)$table
                       records n.max n.start events    rmean se(rmean)   median  0.95LCL 0.95UCL
giniGroup=Above median      50    50      50     20 3.889363 0.2358844       NA 4.799452      NA
giniGroup=Under median      57    57      57     31 3.523674 0.2151269 4.071184 2.945927      NA

without sensoring

fig2AC_NoCensor_test <- survfit(Surv(OS_years_20190329, status_out_20190329) ~ giniGroup, data = GiniClin_tumor[GiniClin_tumor$histology_Hans_B_WHO_2015 == "AC", ])

print(fig2AC_NoCensor_test)
Call: survfit(formula = Surv(OS_years_20190329, status_out_20190329) ~ 
    giniGroup, data = GiniClin_tumor[GiniClin_tumor$histology_Hans_B_WHO_2015 == 
    "AC", ])

                        n events median 0.95LCL 0.95UCL
giniGroup=Under median 57     40   4.07    2.95    7.59
giniGroup=Above median 50     28   7.31    4.80      NA
summary(fig2AC_NoCensor_test)$table
                       records n.max n.start events    rmean se(rmean)   median  0.95LCL 0.95UCL
giniGroup=Under median      57    57      57     40 6.139774 0.6418922 4.071184 2.945927 7.59206
giniGroup=Above median      50    50      50     28 7.749610 0.7251560 7.305955 4.799452      NA
ggsurvplot(fig2AC_NoCensor_test,
          pval = TRUE,
          palette = c("#e64b35", "#4dbbd5"),
          break.time.by = 1,
          ggtheme = theme_classic(),
          legend.labs = c("Above median", "Under median"),
          risk.table = "abs_pct",
          risk.table.y.text = FALSE,
          xlab = "Time (years)",
          title = "giniSurv_without_censoring",
          axes.offset = FALSE,
          risk.table.fontsize = 2.5,
          legend = c(0.9,0.9),
          risk.table.title = "Number at risk by time: n (%)",
          font.main = c())

SqCC patient

GiniClin_tumor_SqCC = GiniClin_tumor[GiniClin_tumor$histology_Hans_B_WHO_2015 == "SqCC", ]

fig2SqCCtest_2 <- survfit(Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ giniGroup, data = GiniClin_tumor_SqCC)

print(fig2SqCCtest)
Call: survfit(formula = Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ 
    giniGroup, data = GiniClin_SqCC)

                        n events median 0.95LCL 0.95UCL
giniGroup=Above median 41     21   4.86    3.20      NA
giniGroup=Under median 32     12     NA    4.39      NA
print("====")
[1] "===="
summary(fig2SqCCtest)$table
                       records n.max n.start events    rmean se(rmean)   median  0.95LCL 0.95UCL
giniGroup=Above median      41    41      41     21 3.366955 0.2968385 4.856947 3.195072      NA
giniGroup=Under median      32    32      32     12 4.213723 0.2114153       NA 4.388775      NA

fig2_SqCC_timespl <- survSplit(Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329 == 1) ~ ., data=GiniClin_tumor_SqCC, cut=2, episode = "tgroup")

fig2_SqCC_timespl.cox <- coxph(Surv(tstart, OS_years_5_years_trunk_20190329, event==1) ~ giniGroup:strata(tgroup), data=fig2_SqCC_timespl, ties="efron")
summary(fig2_SqCC_timespl.cox)
Call:
coxph(formula = Surv(tstart, OS_years_5_years_trunk_20190329, 
    event == 1) ~ giniGroup:strata(tgroup), data = fig2_SqCC_timespl, 
    ties = "efron")

  n= 109, number of events= 28 

                                                coef exp(coef) se(coef)      z Pr(>|z|)  
giniGroupAbove median:strata(tgroup)tgroup=1  1.7134    5.5476   0.7602  2.254   0.0242 *
giniGroupUnder median:strata(tgroup)tgroup=1      NA        NA   0.0000     NA       NA  
giniGroupAbove median:strata(tgroup)tgroup=2 -0.9789    0.3757   0.6018 -1.627   0.1038  
giniGroupUnder median:strata(tgroup)tgroup=2      NA        NA   0.0000     NA       NA  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

                                             exp(coef) exp(-coef) lower .95 upper .95
giniGroupAbove median:strata(tgroup)tgroup=1    5.5476     0.1803    1.2503    24.615
giniGroupUnder median:strata(tgroup)tgroup=1        NA         NA        NA        NA
giniGroupAbove median:strata(tgroup)tgroup=2    0.3757     2.6615    0.1155     1.222
giniGroupUnder median:strata(tgroup)tgroup=2        NA         NA        NA        NA

Concordance= 0.652  (se = 0.039 )
Likelihood ratio test= 10.24  on 2 df,   p=0.006
Wald test            = 7.73  on 2 df,   p=0.02
Score (logrank) test = 9.3  on 2 df,   p=0.01

without sensoring

fig2SqCC_NoCensor_test <- survfit(Surv(OS_years_20190329, status_out_20190329) ~ giniGroup, data = GiniClin_tumor[GiniClin_tumor$histology_Hans_B_WHO_2015 == "SqCC", ])

print(fig2SqCC_NoCensor_test)
Call: survfit(formula = Surv(OS_years_20190329, status_out_20190329) ~ 
    giniGroup, data = GiniClin_tumor[GiniClin_tumor$histology_Hans_B_WHO_2015 == 
    "SqCC", ])

                        n events median 0.95LCL 0.95UCL
giniGroup=Under median 26     21   6.38    3.50    8.97
giniGroup=Above median 36     22   7.05    1.96      NA
summary(fig2SqCC_NoCensor_test)$table
                       records n.max n.start events    rmean se(rmean)   median  0.95LCL  0.95UCL
giniGroup=Under median      26    26      26     21 6.777249 0.7798128 6.384668 3.501711 8.969199
giniGroup=Above median      36    36      36     22 7.032550 0.8931418 7.052704 1.960301       NA
ggsurvplot(fig2SqCC_NoCensor_test,
          pval = TRUE,
          palette = c("#e64b35", "#4dbbd5"),
          break.time.by = 1,
          ggtheme = theme_classic(),
          legend.labs = c("Above median", "Under median"),
          risk.table = "abs_pct",
          risk.table.y.text = FALSE,
          xlab = "Time (years)",
          title = "giniSurv_without_censoring",
          axes.offset = FALSE,
          risk.table.fontsize = 2.5,
          legend = c(0.9,0.9),
          risk.table.title = "Number at risk by time: n (%)",
          font.main = c())

Table: Cox regression

Single variate

fig2.cox <- coxph(Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ giniGroup, data = GiniClin_tumor)

print("===")
[1] "==="
fig2.cox
Call:
coxph(formula = Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ 
    giniGroup, data = GiniClin_tumor)

                         coef exp(coef) se(coef)      z    p
giniGroupAbove median -0.1166    0.8900   0.2165 -0.539 0.59

Likelihood ratio test=0.29  on 1 df, p=0.5898
n= 182, number of events= 86 
print("===")
[1] "==="
print(summary(fig2.cox))
Call:
coxph(formula = Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ 
    giniGroup, data = GiniClin_tumor)

  n= 182, number of events= 86 

                         coef exp(coef) se(coef)      z Pr(>|z|)
giniGroupAbove median -0.1166    0.8900   0.2165 -0.539     0.59

                      exp(coef) exp(-coef) lower .95 upper .95
giniGroupAbove median      0.89      1.124    0.5822      1.36

Concordance= 0.503  (se = 0.028 )
Likelihood ratio test= 0.29  on 1 df,   p=0.6
Wald test            = 0.29  on 1 df,   p=0.6
Score (logrank) test = 0.29  on 1 df,   p=0.6
print("===")
[1] "==="
cox.zph(fig2.cox)
          chisq df     p
giniGroup  5.22  1 0.022
GLOBAL     5.22  1 0.022
# Merge the histology group except AC and SqCC to others
GiniClin_tumor[!(GiniClin_tumor$histology_Hans_B_WHO_2015 %in% c("AC","SqCC")), "Histology"] <- "Other"
GiniClin_tumor[GiniClin_tumor$histology_Hans_B_WHO_2015 == "AC", "Histology"] <- "AC"
GiniClin_tumor[GiniClin_tumor$histology_Hans_B_WHO_2015 == "SqCC", "Histology"] <- "SqCC"
# Merge the current smoke and former smoke in to one group
GiniClin_tumor[GiniClin_tumor$smoke %in% c("Current smoke","Former smoke"), "smokeGroup"] <- "Current/Former"
GiniClin_tumor[GiniClin_tumor$smoke == "Never smoke", "smokeGroup"] <- "Never"
# Construct levels of each parameter
GiniClin_tumor$stageGroup = factor(GiniClin_tumor$stageGroup, levels = c("Low stage", "High stage"))
GiniClin_tumor$gender = factor(GiniClin_tumor$gender, levels = c("Male", "Female"))
GiniClin_tumor$Histology = factor(GiniClin_tumor$Histology, levels = c("AC", "SqCC", "Other"))
GiniClin_tumor$ageGroup = factor(GiniClin_tumor$ageGroup, levels = c("Under 70", "Above 70"))
GiniClin_tumor$smokeGroup = factor(GiniClin_tumor$smokeGroup, levels = c("Never","Current/Former"))

Multi-variate cox regression

fig2.multicox <- coxph(Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ giniGroup + ageGroup + gender + smokeGroup + Histology + stageGroup, data = GiniClin_tumor)

summary(fig2.multicox)
Call:
coxph(formula = Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ 
    giniGroup + ageGroup + gender + smokeGroup + Histology + 
        stageGroup, data = GiniClin_tumor)

  n= 182, number of events= 86 

                             coef exp(coef) se(coef)      z Pr(>|z|)   
giniGroupAbove median    -0.04817   0.95298  0.22266 -0.216  0.82874   
ageGroupAbove 70          0.23155   1.26055  0.21842  1.060  0.28910   
genderFemale             -0.24394   0.78354  0.22166 -1.101  0.27110   
smokeGroupCurrent/Former  0.23605   1.26624  0.39017  0.605  0.54518   
HistologySqCC            -0.18836   0.82832  0.24177 -0.779  0.43592   
HistologyOther           -0.20626   0.81362  0.44507 -0.463  0.64305   
stageGroupHigh stage      0.58274   1.79095  0.22201  2.625  0.00867 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

                         exp(coef) exp(-coef) lower .95 upper .95
giniGroupAbove median       0.9530     1.0493    0.6160     1.474
ageGroupAbove 70            1.2605     0.7933    0.8216     1.934
genderFemale                0.7835     1.2763    0.5074     1.210
smokeGroupCurrent/Former    1.2662     0.7897    0.5894     2.720
HistologySqCC               0.8283     1.2073    0.5157     1.330
HistologyOther              0.8136     1.2291    0.3401     1.947
stageGroupHigh stage        1.7909     0.5584    1.1591     2.767

Concordance= 0.616  (se = 0.028 )
Likelihood ratio test= 10.84  on 7 df,   p=0.1
Wald test            = 10.91  on 7 df,   p=0.1
Score (logrank) test = 11.15  on 7 df,   p=0.1

Without adjuvent treatment

# Subset the group without adjuvent treatment
GiniClin_noTreat = subset(GiniClin_tumor, Annette_adjuvant == 0)

GiniClin_noTreat = as.data.frame(GiniClin_noTreat)

GiniClin_noTreat$giniGroup = factor(GiniClin_noTreat$giniGroup, levels = c("Above median", "Under median"))

# construct the object
fig8test <- survfit(Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ giniGroup, data = GiniClin_noTreat)

print(fig8test)
Call: survfit(formula = Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ 
    giniGroup, data = GiniClin_noTreat)

                        n events median 0.95LCL 0.95UCL
giniGroup=Above median 48     18     NA      NA      NA
giniGroup=Under median 37     17     NA    3.55      NA
summary(fig8test)$table
                       records n.max n.start events    rmean se(rmean) median  0.95LCL 0.95UCL
giniGroup=Above median      48    48      48     18 3.814767 0.2603937     NA       NA      NA
giniGroup=Under median      37    37      37     17 3.830473 0.2522535     NA 3.545517      NA

# Subset the group without adjuvent treatment
GiniClin_Treat = subset(GiniClin_tumor, Annette_adjuvant == 1)

GiniClin_Treat = as.data.frame(GiniClin_Treat)

GiniClin_Treat$giniGroup = factor(GiniClin_Treat$giniGroup, levels = c("Above median", "Under median"))

# construct the object
fig8test_2 <- survfit(Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ giniGroup, data = GiniClin_Treat)

print(fig8test_2)
Call: survfit(formula = Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ 
    giniGroup, data = GiniClin_Treat)

                        n events median 0.95LCL 0.95UCL
giniGroup=Above median 39     19     NA     3.2      NA
giniGroup=Under median 45     23   4.82     3.5      NA
summary(fig8test_2)$table
                       records n.max n.start events    rmean se(rmean)   median  0.95LCL 0.95UCL
giniGroup=Above median      39    39      39     19 3.523193 0.2922509       NA 3.195072      NA
giniGroup=Under median      45    45      45     23 3.814769 0.2146622 4.824093 3.498973      NA

Figure mutation burden

Mutation burden

mutClin <- read_excel("~/Project/TCR_Summary/Writing/SumSup.xlsx", sheet = "MutationBurdern_all_tumor")

mutClin <- as.data.frame(mutClin, row.names = mutClin$ID)

mutClin$AB_GiniIndex <- as.numeric(mutClin$AB_GiniIndex)
mutClin$Mutation_load_allmutations <- as.numeric(mutClin$Mutation_load_allmutations)
mutClin <- mutClin[intersect(rownames(mutClin), rownames(GiniClin_tumor)),]
fig4a <- ggscatter(mutClin[,c("AB_GiniIndex","Mutation_load_allmutations")], x = "AB_GiniIndex", y = "Mutation_load_allmutations",
                   add="reg.line", add.params = list(color = "#00bfc4"),
                   conf.int = FALSE,
                   cor.coef = TRUE,
                   cor.coeff.args = list(method = "spearman", label.x.npc = 0.15, label.y.npc = 0.85),
                   ggtheme = theme_classic(),
                   #add = "reg.line", add.params = c(color = '#00bfc4'),
                   title = "Mutation burden", xlab = "Gini Index", ylab = "Mutation load of all mutations",
                   font.tickslab = c(size=15, color = "black"), font.main = 20,font.y = 15, font.x = 15) +
  scale_y_continuous(expand = c(0,0), limits = c(0, 130), breaks = c(seq(0,120,30))) +
  scale_x_continuous(expand = c(0,0), limits = c(0, 0.75), breaks = c(seq(0,0.6,0.2)))

fig4a
`geom_smooth()` using formula 'y ~ x'

Mutation

for (mutGene in colnames(mutGini[,(3:84)])){
  WT_buff <- mutGini[mutGini[,mutGene] == "WT","GiniIndex"]
  Mut_buff <- mutGini[mutGini[,mutGene] == "Mutated","GiniIndex"]
  mutRes <- wilcox.test(WT_buff,Mut_buff)
  mutTest <- c(mutTest,c(mutGene,mutRes$statistic,mutRes$p.value))
}
Error in h(simpleError(msg, call)) : 
  error in evaluating the argument 'x' in selecting a method for function 'colnames': undefined columns selected

EGFR

APC

f4c.apc <- ggplot(mutGini, aes(x = APC, y = GiniIndex, fill=APC)) +
  geom_boxplot(outlier.colour = "black", outlier.shape = 16, outlier.size = 2, colour = "black") +
  theme_classic() +
  # coord_flip() +
  scale_fill_manual(values = c("#FFE5D4", "#E6EBE0")) +
  labs(title = "APC", x = NULL) +
  theme(legend.position = "none",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20)) +
  stat_compare_means(paired = FALSE)
f4c.apc

TP53

f4c.tp53 <- ggplot(mutGini, aes(x = TP53, y = GiniIndex, fill=TP53)) +
  geom_boxplot(outlier.colour = "black", outlier.shape = 16, outlier.size = 2, colour = "black") +
  theme_classic() +
  # coord_flip() +
  scale_fill_manual(values = c("#FFE5D4", "#E6EBE0")) +
  labs(title = "TP53", x = NULL) +
  theme(legend.position = "none",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20)) +
  stat_compare_means(paired = FALSE)
f4c.tp53

ARID1A

f4c.arid1a <- ggplot(mutGini, aes(x = ARID1A, y = GiniIndex, fill=ARID1A)) +
  geom_boxplot(outlier.colour = "black", outlier.shape = 16, outlier.size = 2, colour = "black") +
  theme_classic() +
  # coord_flip() +
  scale_fill_manual(values = c("#FFE5D4", "#E6EBE0")) +
  labs(title = "ARID1A", x = NULL) +
  theme(legend.position = "none",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20)) +
  stat_compare_means(paired = FALSE)
f4c.arid1a

EPHB6

f4c.ephb6 <- ggplot(mutGini, aes(x = EPHB6, y = GiniIndex, fill=EPHB6)) +
  geom_boxplot(outlier.colour = "black", outlier.shape = 16, outlier.size = 2, colour = "black") +
  theme_classic() +
  # coord_flip() +
  scale_fill_manual(values = c("#FFE5D4", "#E6EBE0")) +
  labs(title = "EPHB6", x = NULL) +
  theme(legend.position = "none",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20)) +
  stat_compare_means(paired = FALSE)
f4c.ephb6

CSMD3

f4c.csmd3 <- ggplot(mutGini, aes(x = CSMD3, y = GiniIndex, fill=CSMD3)) +
  geom_boxplot(outlier.colour = "black", outlier.shape = 16, outlier.size = 2, colour = "black") +
  theme_classic() +
  # coord_flip() +
  scale_fill_manual(values = c("#FFE5D4", "#E6EBE0")) +
  labs(title = "CSMD3", x = NULL) +
  theme(legend.position = "none",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20, hjust = 0.5)) +
  #, panel.border = element_rect(color = "black", size = 1, fill = NA)
  stat_compare_means(paired = FALSE)
f4c.csmd3

Combine

ggarrange(f4c.egfr, f4c.apc, f4c.tp53, f4c.arid1a, f4c.ephb6, f4c.csmd3, ncol = 2, nrow = 3, align = "hv")

Figure IHC Heatmap

prepare table

ihcAnno <- merge(ihcAnno, mut_t_anno[,c("APC","ARID1A","EPHB6")],by = "row.names", all=FALSE)
Error in h(simpleError(msg, call)) : 
  error in evaluating the argument 'y' in selecting a method for function 'merge': undefined columns selected
ihcAnno_color = list(
  "Gini index" = colorRampPalette(brewer.pal(n = 10, name = "Reds"))(100),
  "KRAS" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "EGFR" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "PIK3CA" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "FGFR2"= c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "PDGFRA"= c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "ROS1"= c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "NF1" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "STK11" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "TP53" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "KEAP1" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "NFE2L2" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "MUC16" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "KMT2C" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "KMT2D" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "SMARCA4" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "CDKN2A" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "CREBBP" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "CSMD3" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "LRP1B" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "APC" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "ARID1A" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "EPHB6" = c(Mutated = "#D45F51", WT = "#B7D2E8"),
  "histology" = c(AC = "#D55740", SqCC = "#4DBCD6", AdSq = "#479E88", LCC = "#415384", LCNEC = "#F49B7F", SC = "#F8BED6"),
  "gender" = c(Male = "#B9E3DF", Female = "#EFC0D5"),
  "smoke" = c(Current = "#D45F51", Former = "#E68840", Never = "#BCD9B2"),
  "surv5years" = c(Dead = "#D45F51", Alive = "#B7D2E8")
)
Warning: n too large, allowed maximum for palette Reds is 9
Returning the palette you asked for with that many colors
fig5b <- pheatmap(t(ihcHeatT_tumor_norm2), clustering_method = "ward.D2",
                  clustering_distance_rows = "euclidean", clustering_distance_cols = "euclidean",
                  cutree_cols = 3,
                  #color = colorRampPalette(brewer.pal(n = 7, name = "YlGnBu"))(100),
                  annotation_col = ihcAnno,
                  annotation_colors = ihcAnno_color,
                  fontsize = 5,
                  show_colnames = F
                  )
fig5b
fig5b.cluster <- fig5b$tree_col

fig5b.cluster.plot <- plot(fig5b.cluster, hang = -1, cex=0.6, axes=FALSE, ann=FALSE)

fig5b.cut <- cutree(fig5b.cluster, 3)

fig5b.cut_1 <- names(fig5b.cut)[fig5b.cut == 1]
fig5b.cut_2 <- names(fig5b.cut)[fig5b.cut == 2]
fig5b.cut_3 <- names(fig5b.cut)[fig5b.cut == 3]

fig5b.cut_gini <- merge(AB_Gini_anno, fig5b.cut, by = "row.names", all.y = TRUE)

fig5b.cut_gini <- as.data.frame(fig5b.cut_gini, row.names = fig5b.cut_gini$Row.names)

fig5b.cut_gini$Row.names <- NULL

fig5b.cut_gini <- rename(fig5b.cut_gini, c("y"="Cluster"))
fig5b.cut_gini[fig5b.cut_gini$Cluster == 2, "Class"] <- "Immune hot"
fig5b.cut_gini[fig5b.cut_gini$Cluster == 3, "Class"] <- "Median"
fig5b.cut_gini[fig5b.cut_gini$Cluster == 1, "Class"] <- "Immune cold"
fig5b.cut_gini$Class = factor(fig5b.cut_gini$Class, levels = c("Immune hot", "Median", "Immune cold"))
fig5b.cut_gini <- as.data.frame(fig5b.cut_gini)
fig5b.cut_gini2 <- rename(fig5b.cut_gini, c("Gini index"="GiniIndex"))
compare_means(GiniIndex ~ Class, data = fig5b.cut_gini2)
fig5b.cut_km <- merge(fig5b.cut_gini, GiniClin_tumor[, c("OS_years_5_years_trunk_20190329", "status_5_years_trunk_20190329")], by = "row.names")
fig5b.cut_km <- as.data.frame(fig5b.cut_km, row.names = fig5b.cut_km$Row.names)
fig5b.cut_km$Row.names <- NULL

fig5b.test <- survfit(Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ Class, data = fig5b.cut_km)

summary(fig5b.test)$table
fig5b.KM <- ggsurvplot(fig5b.test,
                        pval = TRUE,
                        palette = c("#e64b35", "#4dbbd5", "#999999"),
                        break.time.by = 1,
                        ggtheme = theme_classic(),
                        #legend.labs = c("Above median", "Under median"),
                        risk.table = "abs_pct",
                        risk.table.y.text = FALSE,
                        xlab = "Time (years)",
                        title = "giniSurv_Class",
                        xlim = c(0,5.2),
                        axes.offset = FALSE,
                        risk.table.fontsize = 2.5,
                        legend = c(0.9,0.9),
                        risk.table.title = "Number at risk by time: n (%)",
                        font.main = c())
fig5b.KM

fig5b.cut_clin <- merge(fig5b.cut_km, GiniClin_tumor[,c("histology_Hans_B_WHO_2015", "gender", "smoke")], by = "row.names", all.x = TRUE)

fig5b.cut_clin <- as.data.frame(fig5b.cut_clin, row.names = fig5b.cut_clin$Row.names)

fig5b.cut_clin$Row.names <- NULL

fig5b.cut_clin_AC <- fig5b.cut_clin[fig5b.cut_clin$histology_Hans_B_WHO_2015 == "AC", ]
fig5b.cut_clin_SqCC <- fig5b.cut_clin[fig5b.cut_clin$histology_Hans_B_WHO_2015 == "SqCC", ]

fig5b.cut_clin

fig5b.cut_clin[fig5b.cut_clin$`Gini index` >= 0.25431, "giniGroup"] <- "Above median"
fig5b.cut_clin[fig5b.cut_clin$`Gini index` < 0.25431, "giniGroup"] <- "Under median"
fig5b.cut_clin$giniGroup = factor(fig5b.cut_clin$giniGroup, levels = c("Above median", "Under median"))

cluster without gini index

pheatmap(t(ihcHeatT_tumor_norm2[,(2:25)]), clustering_method = "ward.D2",
                  clustering_distance_rows = "euclidean", clustering_distance_cols = "euclidean",
                  cutree_cols = 3,
                  #color = colorRampPalette(brewer.pal(n = 7, name = "YlGnBu"))(100),
                  annotation_col = ihcAnno,
                  annotation_colors = ihcAnno_color,
                  fontsize = 5,
                  show_colnames = F
                  )

pheatmap(t(ihcHeatT_tumor_norm3[,grep("_S", colnames(ihcHeatT_tumor_norm3))]), clustering_method = "ward.D2",
          clustering_distance_rows = "euclidean", clustering_distance_cols = "euclidean",
          cutree_cols = 3,
          #color = colorRampPalette(brewer.pal(n = 7, name = "YlGnBu"))(100),
          annotation_col = ihcAnno,
          annotation_colors = ihcAnno_color,
          fontsize = 5,
          show_colnames = F
)
pheatmap(t(ihcHeatT_tumor_norm3[,grep("_S", colnames(ihcHeatT_tumor_norm3))]), clustering_method = "ward.D2",
          clustering_distance_rows = "euclidean", clustering_distance_cols = "euclidean",
          cutree_cols = 3,
          #color = colorRampPalette(brewer.pal(n = 7, name = "YlGnBu"))(100),
          annotation_col = ihcAnno,
          annotation_colors = ihcAnno_color,
          fontsize = 5,
          show_colnames = F
)
pheatmap(t(ihcHeatT_tumor_norm3[,grep("_T", colnames(ihcHeatT_tumor_norm3))]), clustering_method = "ward.D2",
          clustering_distance_rows = "euclidean", clustering_distance_cols = "euclidean",
          cutree_cols = 2,
          #color = colorRampPalette(brewer.pal(n = 7, name = "YlGnBu"))(100),
          annotation_col = ihcAnno,
          annotation_colors = ihcAnno_color,
          fontsize = 5,
          show_colnames = F
)
fig5d_T <- pheatmap(t(ihcHeatT_tumor_norm3[,grep("_T", colnames(ihcHeatT_tumor_norm3))]), clustering_method = "ward.D2",
          clustering_distance_rows = "euclidean", clustering_distance_cols = "euclidean",
          cutree_cols = 2,
          #color = colorRampPalette(brewer.pal(n = 7, name = "YlGnBu"))(100),
          annotation_col = ihcAnno,
          annotation_colors = ihcAnno_color,
          fontsize = 5,
          show_colnames = F
)
fig5d_T
fig5d_T.cluster <- fig5d_T$tree_col

fig5d_T.cluster.plot <- plot(fig5d_T.cluster, hang = -1, cex=0.6, axes=FALSE, ann=FALSE)


fig5d_T.cut <- cutree(fig5d_T.cluster, 2)

fig5d_T.cut_1 <- names(fig5d_T.cut)[fig5d_T.cut == 1]
fig5d_T.cut_2 <- names(fig5d_T.cut)[fig5d_T.cut == 2]

fig5d_T.cut_gini <- merge(AB_Gini_anno, fig5d_T.cut, by = "row.names", all.y = TRUE)

fig5d_T.cut_gini <- as.data.frame(fig5d_T.cut_gini, row.names = fig5d_T.cut_gini$Row.names)

fig5d_T.cut_gini$Row.names <- NULL

fig5d_T.cut_gini <- rename(fig5d_T.cut_gini, c("Cluster"="y"))
fig5d_T.cut_gini[fig5d_T.cut_gini$Cluster == 1, "Class"] <- "Immune cold"
fig5d_T.cut_gini[fig5d_T.cut_gini$Cluster == 2, "Class"] <- "Immune hot"
fig5d_T.cut_gini$Class = factor(fig5d_T.cut_gini$Class, levels = c("Immune hot", "Immune cold"))
fig5d_T.box <- ggplot(fig5d_T.cut_gini, aes(x = Class, y = GiniIndex, fill=Class)) +
    geom_boxplot(outlier.colour = "black", outlier.shape = 16, outlier.size = 2, colour = "black") +
    theme_classic() +
    # coord_flip() +
    scale_fill_manual(values = c("#e64b35", "#4dbbd5")) +
    labs(title = "Class", x = "Class") +
    theme(legend.position = "none",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20)) +
    stat_compare_means(paired = NULL)

fig5d_T.box

fig5d_T.cut_km <- merge(fig5d_T.cut_gini, GiniClin_tumor[, c("OS_years_5_years_trunk_20190329", "status_5_years_trunk_20190329")], by = "row.names")
fig5d_T.cut_km <- as.data.frame(fig5d_T.cut_km, row.names = fig5d_T.cut_km$Row.names)
fig5d_T.cut_km$Row.names <- NULL

fig5d_T.test <- survfit(Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ Class, data = fig5d_T.cut_km)

summary(fig5d_T.test)$table
                  records n.max n.start events    rmean se(rmean) median  0.95LCL 0.95UCL
Class=Immune hot       39    39      39     18 3.704189 0.2816978     NA 4.388775      NA
Class=Immune cold     138   138     138     65 3.737826 0.1381891     NA 4.276523      NA
ggsurvplot(fig5d_T.test,
         pval = TRUE,
         palette = c("#e64b35", "#4dbbd5", "#999999"),
         break.time.by = 1,
         ggtheme = theme_classic(),
         #legend.labs = c("Above median", "Under median"),
         risk.table = "abs_pct",
         risk.table.y.text = FALSE,
         xlab = "Time (years)",
         title = "giniSurv_Class",
         xlim = c(0,5.2),
         axes.offset = FALSE,
         risk.table.fontsize = 2.5,
         legend = c(0.9,0.9),
         risk.table.title = "Number at risk by time: n (%)",
         font.main = c())

fig5d_S.cluster <- fig5d_S$tree_col

fig5d_S.cluster.plot <- plot(fig5d_S.cluster, hang = -1, cex=0.6, axes=FALSE, ann=FALSE)

fig5d_S.cut <- cutree(fig5d_S.cluster, 3)

fig5d_S.cut_1 <- names(fig5d_S.cut)[fig5d_S.cut == 1]
fig5d_S.cut_2 <- names(fig5d_S.cut)[fig5d_S.cut == 2]
fig5d_S.cut_3 <- names(fig5d_S.cut)[fig5d_S.cut == 3]

fig5d_S.cut_gini <- merge(AB_Gini_anno, fig5d_S.cut, by = "row.names", all.y = TRUE)

fig5d_S.cut_gini <- as.data.frame(fig5d_S.cut_gini, row.names = fig5d_S.cut_gini$Row.names)

fig5d_S.cut_gini$Row.names <- NULL

fig5d_S.cut_gini <- rename(fig5d_S.cut_gini, c("Cluster"="y"))
fig5d_S.cut_gini[fig5d_S.cut_gini$Cluster == 1, "Class"] <- "Immune cold"
fig5d_S.cut_gini[fig5d_S.cut_gini$Cluster == 2, "Class"] <- "Immune median"
fig5d_S.cut_gini[fig5d_S.cut_gini$Cluster == 3, "Class"] <- "Immune hot"
fig5d_S.cut_gini$Class = factor(fig5d_S.cut_gini$Class, levels = c("Immune hot", "Median", "Immune cold"))

fig5d_S.cut_km <- merge(fig5d_S.cut_gini, GiniClin_tumor[, c("OS_years_5_years_trunk_20190329", "status_5_years_trunk_20190329")], by = "row.names")
fig5d_S.cut_km <- as.data.frame(fig5d_S.cut_km, row.names = fig5d_S.cut_km$Row.names)
fig5d_S.cut_km$Row.names <- NULL

fig5d_S.test <- survfit(Surv(OS_years_5_years_trunk_20190329, status_5_years_trunk_20190329) ~ Class, data = fig5d_S.cut_km)

summary(fig5d_S.test)$table
                  records n.max n.start events    rmean se(rmean) median  0.95LCL 0.95UCL
Class=Immune hot       36    36      36     14 3.885352 0.2702259     NA 4.544832      NA
Class=Median           62    62      62     30 3.669780 0.2112939     NA 3.556468      NA
Class=Immune cold      79    79      79     39 3.707397 0.1864731     NA 4.010951      NA
ggsurvplot(fig5d_S.test,
         pval = TRUE,
         palette = c("#e64b35", "#4dbbd5", "#999999"),
         break.time.by = 1,
         ggtheme = theme_classic(),
         #legend.labs = c("Above median", "Under median"),
         risk.table = "abs_pct",
         risk.table.y.text = FALSE,
         xlab = "Time (years)",
         title = "giniSurv_Class",
         xlim = c(0,5.2),
         axes.offset = FALSE,
         risk.table.fontsize = 2.5,
         legend = c(0.9,0.9),
         risk.table.title = "Number at risk by time: n (%)",
         font.main = c())
ihcHeatT_tumor_norm4 <- rename_with(ihcHeatT_tumor_norm4, gsub("SQ1", "_"))
Error in is.factor(x) : argument "x" is missing, with no default

fig5d_ST.cut_gini[fig5d_ST.cut_gini$Cluster == 1, "Class"] <- "Immune cold"
fig5d_ST.cut_gini[fig5d_ST.cut_gini$Cluster == 2, "Class"] <- "Immune hot"
fig5d_ST.cut_gini$Class = factor(fig5d_ST.cut_gini$Class, levels = c("Immune hot", "Immune cold"))
fig5d_ST.cut_gini <- as.data.frame(fig5d_ST.cut_gini)
fig5d_ST.cut_gini <- rename(fig5d_ST.cut_gini, c("GiniIndex"="Gini index"))
compare_means(GiniIndex ~ Class, data = fig5d_ST.cut_gini)

Ordered by Gini

pheatmap(t(ihcHeatT_tumor_norm4[order(ihcHeatT_tumor_norm4$GiniIndex),c(2:12)]),
         #clustering_method = "ward.D2",
         cluster_rows = F, cluster_cols = F,
         cutree_cols = 2,
         #color = colorRampPalette(brewer.pal(n = 7, name = "YlGnBu"))(100),
         annotation_col = ihcAnno,
         annotation_colors = ihcAnno_color,
         fontsize = 8,
         show_colnames = F)

IHC correlation plot

fig6 <- corrplot(data.matrix(ihcCorR), method = "circle",col = rev(COL2('RdBu', 200)),
                 p.mat = data.matrix(ihcCorP), insig = "label_sig", sig.level = c(.001, .01, .05), pch.cex = 0.8,
                 tl.col = "black")
fig6
ggplot(ihcCorP_melt, aes(var1, var2, fill = Corr)) +
  geom_point(shape=21, colour = "black", size = 12)+
  theme_classic()+
  scale_fill_gradientn(colours = rev(brewer.pal(5, "Spectral")))+
  labs(title = "Correlation", x = "IHC marker", y = "Position") +
  theme(axis.text = element_text(size = 10, colour = "black"), axis.title = element_text(size = 10),plot.title = element_text(size=15))+
  geom_text(aes(label = label), size = 5, colour = "black")
Warning: Removed 10 rows containing missing values (geom_text).

Figure 9 Lymphotrack cluster plot

L481

L481_L <- as.data.frame(L481_L)

L481_R <- as.data.frame(L481_R)

L481_all <- as.data.frame(L481_all)

L481_L["Class"] <- "Lymphotrack"

L481_R["Class"] <- "RNAseq"
npj.pal = pal_npg("nrc", alpha = 0.9)(10)
simp.pal = pal_simpsons("springfield")(16)
nejm.pal = pal_nejm("default", alpha = 0.9)(8)
jama.pal = pal_jama("default",alpha = 0.9)(7)
fig9_pal = c(c("#E0E3E3FF"), npj.pal, simp.pal, nejm.pal, jama.pal)

fig9_L481 <- ggplot(L481_all, aes(x= Type, y= Fraction, fill= Clone)) +
  geom_col(position = "stack", width = 0.6) +
  theme_classic() +
  scale_y_continuous(expand = c(0,0)) +
  scale_fill_manual(values = fig9_pal) +
  scale_y_break(c(40,95), scales = 0.2, ticklabels = c(95,100))


gg.gap(plot = fig9_L481,
       segments = c(40,80),
       ylim = c(0, 100),
       tick_width = c(5, 10),
       rel_heights = c(0.3, 0, 0.1)
       )

ggplot(L481_L, aes(x=Class, y= Fraction, fill= reorder(Lymphotrack, -Fraction))) +
     geom_col(position = "stack", width = 0.6) +
     theme_classic() +
     scale_fill_manual(values = fig9_pal) +
     scale_y_break(c(7,92), scales = 0.2, ticklabels = c(95,100), expand = FALSE) +
     scale_y_continuous(expand = c(0,0), breaks = c(0,2,4,6))

ggplot(L481_R, aes(x=Class, y= Fraction, fill= reorder(RNAseq, -Fraction))) +
     geom_col(position = "stack", width = 0.6) +
     theme_classic() +
     scale_fill_manual(values = fig9_pal) +
     scale_y_break(c(40,92), scales = 0.2, ticklabels = c(95,100), expand = FALSE) +
     scale_y_continuous(expand = c(0,0), breaks = c(0,10,20,30,40))

Fig10 Vocanol plot

fig10 <- ggplot(data = diffGene, aes(x = log2FoldChange, y = -log10(padj), color = sign)) + 
  geom_point(size = 1) +  #Create scatter plot
  scale_color_manual(values = c('red', 'gray', 'green'), limits = c('UP', 'none', 'DOWN')) +  #Set the color
  labs(x = 'log2 Fold Change', y = '-log10 adjust p-value', title = 'High clonality vs Low clonality', color = '') +  #Set the labels
  theme(plot.title = element_text(hjust = 0.5, size = 14), panel.grid = element_blank(), #Change the them and grid lines
  panel.background = element_rect(color = 'black', fill = 'transparent'), 
  legend.key = element_rect(fill = 'transparent')) +
  geom_vline(xintercept = c(-1, 1), lty = 3, color = 'black') +  #Add threshold line
  geom_hline(yintercept = 2, lty = 3, color = 'black') +
  xlim(-12, 12) + ylim(0, 35) + #Set the curve boundary
  geom_text_repel(
    data = diffGene,
    aes(label = label),
    size = 3, segment.color = "blue", show.legned = FALSE,
    point.padding = unit(0.8, "lines")
  )
Warning: Ignoring unknown parameters: `show.legned`

#Figure11 Phenotype

fig11
Warning: Removed 16 rows containing missing values (geom_text).

Cluster

All gini

This method start from the t cell pheno type data to check if the gini index is linked with these group. But there is also a angle that start from Gini index (25%) to analyze the t cell composition changes

phenoClin_gini3 <- phenoClin_gini2[, grep("Pan", colnames(phenoClin_gini2), invert = T)]
Error: unexpected symbol in:
"phenoClin_gini3 <- phenoClin_gini2[, grep("Pan", colnames(phenoClin_gini2), invert = T)
phenoClin_gini3"
min.max.norm <- function(x){
  (x - min(x, na.rm = TRUE))/(max(x, na.rm = TRUE) - min(x, na.rm = TRUE))
}

phenoClin_gini3.norm2 <- apply(phenoClin_gini3[, c(2:40)], 2, min.max.norm)
phenoClin_gini3.norm2 <- as.data.frame(phenoClin_gini3.norm2)
phenoClin_gini3.norm2 <- cbind(phenoClin_gini3[,1], phenoClin_gini3.norm2)
colnames(phenoClin_gini3.norm2)[colnames(phenoClin_gini3.norm2) == "phenoClin_gini3[, 1]"] = "GiniIndex"
pheatmap(t(phenoClin_gini2[,grep("st_", colnames(phenoClin_gini2), invert = T)]), clustering_method = "ward.D2",
        clustering_distance_rows = "euclidean", clustering_distance_cols = "euclidean",
        cutree_cols = 2,
        #color = colorRampPalette(brewer.pal(n = 7, name = "YlGnBu"))(100),
        annotation_col = ihcAnno,
        annotation_colors = ihcAnno_color,
        fontsize = 5,
        show_colnames = F)

pheatmap(t(phenoClin_gini3.norm[,c(1,grep("st_", colnames(phenoClin_gini3.norm[,c(2:16)]), invert = T)+1)]), clustering_method = "ward.D2",
         clustering_distance_rows = "euclidean", clustering_distance_cols = "euclidean",
         cutree_cols = 2,
         #color = colorRampPalette(brewer.pal(n = 7, name = "YlGnBu"))(100),
         annotation_col = ihcAnno,
         annotation_colors = ihcAnno_color,
         fontsize = 5,
         show_colnames = F)
pheatmap(t(phenoClin_gini3.norm2[,grep("st_", colnames(phenoClin_gini3.norm2[,c(1:16)]), invert = T)]), clustering_method = "ward.D2",
         clustering_distance_rows = "euclidean", clustering_distance_cols = "euclidean",
         cutree_cols = 2,
         #color = colorRampPalette(brewer.pal(n = 7, name = "YlGnBu"))(100),
         annotation_col = ihcAnno,
         annotation_colors = ihcAnno_color,
         fontsize = 5,
         show_colnames = F)

pheatmap(t(phenoClin_gini3.norm2[,grep("st_", colnames(phenoClin_gini3.norm2[,c(2:16)]))]), clustering_method = "ward.D2",
          cluster_rows = F, clustering_distance_cols = "euclidean",
          cutree_cols = 5,
          #color = colorRampPalette(brewer.pal(n = 9, name = "YlOrBr"))(100),
          annotation_col = ihcAnno,
          annotation_colors = ihcAnno_color,
          fontsize = 5,
          show_colnames = F)

pheatmap(t(phenoClin_gini3.norm2[,grep("st_", colnames(phenoClin_gini3.norm2[,c(2:13)]))+1]), clustering_method = "ward.D2",
         cluster_rows = F, clustering_distance_cols = "euclidean",
         cutree_cols = 4,
         #color = colorRampPalette(brewer.pal(n = 9, name = "YlOrBr"))(100),
         annotation_col = ihcAnno,
         annotation_colors = ihcAnno_color,
         fontsize = 10,
         show_colnames = F)

fig11c.cut_gini <- merge(phenoClin_gini3.norm2[!(rownames(phenoClin_gini3.norm2) == "L464T"),c(1,grep("st_", colnames(phenoClin_gini3.norm2[,c(1:14)])))],
                         fig11c.cut, by = "row.names", all.y = TRUE)
fig11c.cut_gini <- as.data.frame(fig11c.cut_gini, row.names = fig11c.cut_gini$Row.names)
fig11c.cut_gini$Row.names <- NULL
colnames(fig11c.cut_gini)[colnames(fig11c.cut_gini) == "y"] <- "CutGroup"
fig11c.cut_gini$CutGroup = factor(fig11c.cut_gini$CutGroup)
ggplot(fig11c.cut_gini, aes(x = CutGroup, y = GiniIndex, fill=CutGroup)) +
  geom_boxplot(outlier.colour = "black", outlier.shape = 16, outlier.size = 2, colour = "black", notch = FALSE) +
  theme_classic() +
  #coord_flip() +
  #scale_color_npg() +
  labs(title = "Gini", x = "Group") +
  theme(legend.position = "none",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20)) +
  stat_compare_means(paired = NULL)

ggplot(fig11c.cut_gini, aes(x = CutGroup, y = s_CD4_Treg, fill=CutGroup)) +
  geom_boxplot(outlier.colour = "black", outlier.shape = 16, outlier.size = 2, colour = "black", notch = FALSE) +
  theme_classic() +
  #coord_flip() +
  #scale_color_npg() +
  labs(title = "CD4_Treg", x = "Group") +
  theme(legend.position = "none",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20)) +
  stat_compare_means(paired = NULL)

ggplot(fig11c.cut_gini.melt, aes(x = variable, y = value, fill=variable)) +
  geom_boxplot(outlier.colour = "black", outlier.shape = 16, outlier.size = 2, colour = "black", notch = FALSE) +
  theme_classic() +
  #coord_flip() +
  scale_fill_npg(palette = c("nrc"), alpha=1) +
  labs(x = "T cell phenotype") +
  theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20)) +
  facet_wrap(~CutGroup,ncol = 1)

Smooth line

fig11c.cut_gini.melt2 <- melt(cbind("ID"=rownames(fig11c.cut_gini),fig11c.cut_gini[,c(1:5)]), na.rm = F, id.vars = c("ID", "GiniIndex"), variable.factor =F)

fig11c.cut_gini.melt2$variable <- as.factor(fig11c.cut_gini.melt2$variable)

# Smooth value trend line
ggplot(fig11c.cut_gini.melt2, aes(x = GiniIndex, y = value)) +
  geom_smooth(aes(color=variable,fill=variable), method = "loess") +
  theme_classic() +
  #coord_flip() +
  scale_color_npg(palette = c("nrc"), alpha=1) +
  scale_fill_npg(palette = c("nrc"), alpha=1) +
  labs(x = "Gini coefficient") +
  theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))

# Raw stacking value
ggplot(fig11c.cut_gini.melt2, aes(x = GiniIndex, y = value,fill=variable)) +
  geom_area() +
  theme_classic() +
  #coord_flip() +
  scale_color_npg(palette = c("nrc"), alpha=1) +
  scale_fill_npg(palette = c("nrc"), alpha=1) +
  labs(x = "Gini coefficient") +
  theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))

# Raw fraction change
ggplot(fig11c.cut_gini.melt2, aes(x = GiniIndex, y = value,fill=variable)) +
    geom_area(position = "fill") +
    theme_classic() +
    #coord_flip() +
    scale_color_npg(palette = c("nrc"), alpha=0.8) +
    scale_fill_npg(palette = c("nrc"), alpha=0.8) +
    labs(x = "Gini coefficient") +
    theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))

# smooth density value
ggplot(fig11c.cut_gini.melt2, aes(x = GiniIndex, y = value,fill=variable)) +
  geom_area(fill=NA) +
  stat_smooth(geom = "area", method = "loess", span = 1/3, alpha=0.4)+
  theme_classic() +
  #coord_flip() +
  scale_color_npg(palette = c("nrc"), alpha=1) +
  scale_fill_npg(palette = c("nrc"), alpha=1) +
  labs(x = "Gini coefficient") +
  theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))

# Smooth stacking density value
ggplot(fig11c.cut_gini.melt2, aes(x = GiniIndex, y = value)) +
    stat_smooth(aes(color=variable,fill=variable), method = "loess", geom="area", position = "stack",span = 0.5) +
    theme_classic() +
    #coord_flip() +
    scale_color_npg(palette = c("nrc"), alpha=1) +
    scale_fill_npg(palette = c("nrc"), alpha=0.7) +
    labs(x = "Gini coefficient") +
    theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))

# Smooth fraction changes
ggplot(fig11c.cut_gini.melt2, aes(x = GiniIndex, y = value)) +
    stat_smooth(aes(color=variable,fill=variable), method = "loess", geom="area", position = "fill",span = 0.3) +
    theme_classic() +
    #coord_flip() +
    scale_color_npg(palette = c("nrc"), alpha=1) +
    scale_fill_npg(palette = c("nrc"), alpha=0.7) +
    labs(x = "Gini coefficient") +
    theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))+
    scale_x_continuous(expand = c(0,0), limits = c(0,0.8)) + scale_y_continuous(expand = c(0,0), limits = c(0,1))


# Raw fraction change of unnormalized data
phenoClin_gini3.melt <- melt(cbind("ID"=rownames(phenoClin_gini3),phenoClin_gini3[,c(1,grep("st_", colnames(phenoClin_gini3[,c(1:13)])))]),
                             na.rm = F, id.vars = c("ID", "GiniIndex"), variable.factor =F)

ggplot(phenoClin_gini3.melt, aes(x = GiniIndex, y = value,fill=variable)) +
    geom_area(position = "fill") +
    theme_classic() +
    #coord_flip() +
    scale_color_npg(palette = c("nrc"), alpha=0.8) +
    scale_fill_npg(palette = c("nrc"), alpha=0.8) +
    labs(x = "Gini coefficient") +
    theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))

# Raw stacking of unnormalized data
ggplot(phenoClin_gini3.melt, aes(x = GiniIndex, y = value,fill=variable)) +
    geom_area(position = "stack") +
    theme_classic() +
    #coord_flip() +
    scale_color_npg(palette = c("nrc"), alpha=0.8) +
    scale_fill_npg(palette = c("nrc"), alpha=0.8) +
    labs(x = "Gini coefficient") +
    theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))

# Smooth fraction change of unnormalized data
ggplot(phenoClin_gini3.melt, aes(x = GiniIndex, y = value)) +
    stat_smooth(aes(color=variable,fill=variable), method = "loess", geom="area", position = "fill",span = 0.3) +
    theme_classic() +
    #coord_flip() +
    scale_color_npg(palette = c("nrc"), alpha=1) +
    scale_fill_npg(palette = c("nrc"), alpha=0.7) +
    labs(x = "Gini coefficient") +
    theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))+
    scale_y_continuous(expand = c(0,0), limits = c(0,1))

# Smooth stacking unnormalized data
ggplot(phenoClin_gini3.melt, aes(x = GiniIndex, y = value)) +
    stat_smooth(aes(color=variable,fill=variable), method = "loess", geom="area", position = "stack",span = 0.3) +
    theme_classic() +
    #coord_flip() +
    scale_color_npg(palette = c("nrc"), alpha=1) +
    scale_fill_npg(palette = c("nrc"), alpha=0.7) +
    labs(x = "Gini coefficient") +
    theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))
fig11_gini <- ggplot(fig11c.cut_gini.melt2, aes(x = GiniIndex, y = 1)) + geom_vline(xintercept=fig11c.cut_gini.melt2[fig11c.cut_gini.melt2$variable == "st_CD4_Eff", "GiniIndex"]) + clean_theme(panel.background = element_blank())
Error in clean_theme(panel.background = element_blank()) : 
  unused argument (panel.background = element_blank())

Ordered by gini

pheatmap(t(phenoClin_gini3.norm2[order(phenoClin_gini3.norm2$GiniIndex),c(2:40)]),
         clustering_method = "ward.D2",
         cluster_rows = F, clustering_distance_cols = "euclidean",
         cutree_cols = 4,
         #color = colorRampPalette(brewer.pal(n = 9, name = "YlOrBr"))(100),
         annotation_col = ihcAnno,
         annotation_colors = ihcAnno_color,
         fontsize = 5,
         show_colnames = F)

pheatmap(t(phenoClin_gini3.norm2[order(phenoClin_gini3.norm2$GiniIndex),c(17:31)]),
         clustering_method = "ward.D2",
         cluster_rows = F, cluster_cols = F,
         cutree_cols = 4,
         #color = colorRampPalette(brewer.pal(n = 9, name = "YlOrBr"))(100),
         annotation_col = ihcAnno,
         annotation_colors = ihcAnno_color,
         fontsize = 5,
         show_colnames = F)

High gini group

fig11d.cut_gini <- merge(phenoClin_gini3.norm2[!(rownames(phenoClin_gini3.norm2) == "L464T"),c(1,grep("st_", colnames(phenoClin_gini3.norm2[,c(1:14)])))],
                         fig11d.cut, by = "row.names", all.y = TRUE)
fig11d.cut_gini <- as.data.frame(fig11d.cut_gini, row.names = fig11d.cut_gini$Row.names)
fig11d.cut_gini$Row.names <- NULL
colnames(fig11d.cut_gini)[colnames(fig11d.cut_gini) == "y"] <- "CutGroup"
fig11d.cut_gini$CutGroup = factor(fig11d.cut_gini$CutGroup)
fig11d.cut_gini.melt <- melt(fig11d.cut_gini, na.rm = F)
Using CutGroup as id variables
# Raw stacking change of unnormalized data (Gini high group)
ggplot(phenoClin_gini3.melt[phenoClin_gini3.melt$GiniIndex >= 0.25431,], aes(x = GiniIndex, y = value,fill=variable)) +
    geom_area(position = "stack") +
    theme_classic() +
    #coord_flip() +
    scale_color_npg(palette = c("nrc"), alpha=0.8) +
    scale_fill_npg(palette = c("nrc"), alpha=0.8) +
    labs(x = "Gini coefficient") +
    theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))

# Smoothed stacking change of unnormalized data (Gini high group)
ggplot(phenoClin_gini3.melt[phenoClin_gini3.melt$GiniIndex >= 0.25431,], aes(x = GiniIndex, y = value)) +
    stat_smooth(aes(color=variable,fill=variable), method = "loess", geom="area", position = "stack",span = 0.3) +
    theme_classic() +
    #coord_flip() +
    scale_color_npg(palette = c("nrc"), alpha=1) +
    scale_fill_npg(palette = c("nrc"), alpha=0.7) +
    labs(x = "Gini coefficient") +
    theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))

# Raw fraction change of unnormalized data (Gini high group)
ggplot(phenoClin_gini3.melt[phenoClin_gini3.melt$GiniIndex >= 0.25431,], aes(x = GiniIndex, y = value,fill=variable)) +
    geom_area(position = "fill") +
    theme_classic() +
    #coord_flip() +
    scale_color_npg(palette = c("nrc"), alpha=0.8) +
    scale_fill_npg(palette = c("nrc"), alpha=0.8) +
    labs(x = "Gini coefficient") +
    theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))

# Smoothed fraction change of unnormalized data (Gini high group)
ggplot(phenoClin_gini3.melt[phenoClin_gini3.melt$GiniIndex >= 0.25431,], aes(x = GiniIndex, y = value)) +
    stat_smooth(aes(color=variable,fill=variable), method = "loess", geom="area", position = "fill",span = 0.3) +
    theme_classic() +
    #coord_flip() +
    scale_color_npg(palette = c("nrc"), alpha=1) +
    scale_fill_npg(palette = c("nrc"), alpha=0.7) +
    labs(x = "Gini coefficient") +
    theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))

# Raw stacking value (Gini high group)
ggplot(fig11c.cut_gini.melt2[fig11c.cut_gini.melt2$GiniIndex >= 0.25431,], aes(x = GiniIndex, y = value,fill=variable)) +
  geom_area() +
  theme_classic() +
  #coord_flip() +
  scale_color_npg(palette = c("nrc"), alpha=1) +
  scale_fill_npg(palette = c("nrc"), alpha=1) +
  labs(x = "Gini coefficient") +
  theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))

# Raw fraction value (Gini high group)
ggplot(fig11c.cut_gini.melt2[fig11c.cut_gini.melt2$GiniIndex >= 0.25431,], aes(x = GiniIndex, y = value,fill=variable)) +
    geom_area(position = "fill") +
    theme_classic() +
    #coord_flip() +
    scale_color_npg(palette = c("nrc"), alpha=0.8) +
    scale_fill_npg(palette = c("nrc"), alpha=0.8) +
    labs(x = "Gini coefficient") +
    theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))

# Smoothed stacking change (Gini high group)
ggplot(fig11c.cut_gini.melt2[fig11c.cut_gini.melt2$GiniIndex >= 0.25431,], aes(x = GiniIndex, y = value)) +
    stat_smooth(aes(color=variable,fill=variable), method = "loess", geom="area", position = "stack",span = 0.5) +
    theme_classic() +
    #coord_flip() +
    scale_color_npg(palette = c("nrc"), alpha=1) +
    scale_fill_npg(palette = c("nrc"), alpha=0.7) +
    labs(x = "Gini coefficient") +
    theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))

# Smoothed fraction change (Gini high group)
ggplot(fig11c.cut_gini.melt2[fig11c.cut_gini.melt2$GiniIndex >= 0.25431,], aes(x = GiniIndex, y = value)) +
    stat_smooth(aes(color=variable,fill=variable), method = "loess", geom="area", position = "fill",span = 0.5) +
    theme_classic() +
    #coord_flip() +
    scale_color_npg(palette = c("nrc"), alpha=1) +
    scale_fill_npg(palette = c("nrc"), alpha=0.7) +
    labs(x = "Gini coefficient") +
    theme(legend.position = "top",axis.text = element_text(size = 15, colour = "black"), axis.title = element_text(size = 15),plot.title = element_text(size=20))

Fig12

PhenoAll <- read_excel("~/Project/BOMI2/bomi2_phenotyped_densities_sep.xlsx", sheet = "All")
PhenoAllNoCK <- read_excel("~/Project/BOMI2/bomi2_phenotyped_densities_sep.xlsx", sheet = "noCK")
PhenoTIL <- read_excel("~/Project/BOMI2/bomi2_phenotyped_densities_sep.xlsx", sheet = "TIL")
PhenoNK <- read_excel("~/Project/BOMI2/bomi2_phenotyped_densities_sep.xlsx", sheet = "NK")
PhenoAPC <- read_excel("~/Project/BOMI2/bomi2_phenotyped_densities_sep.xlsx", sheet = "APC")

PhenoAll <- as.data.frame(PhenoAll)
PhenoAllNoCK <- as.data.frame(PhenoAllNoCK)
PhenoTIL <- as.data.frame(PhenoTIL)
PhenoNK <- as.data.frame(PhenoNK)
PhenoAPC <- as.data.frame(PhenoAPC)

PhenoAll$Location <- factor(PhenoAll$Location, levels = c("Tumor", "Stroma", "SAndT"))
PhenoAllNoCK$Location <- factor(PhenoAllNoCK$Location, levels = c("Tumor", "Stroma", "SAndT"))
PhenoTIL$Location <- factor(PhenoTIL$Location, levels = c("Tumor", "Stroma", "SAndT"))
PhenoNK$Location <- factor(PhenoNK$Location, levels = c("Tumor", "Stroma", "SAndT"))
PhenoAPC$Location <- factor(PhenoAPC$Location, levels = c("Tumor", "Stroma", "SAndT"))

PhenoAll$PhenoType <- factor(PhenoAll$PhenoType, levels = c("CD4_Eff","CD4_Treg","CD8_Eff","CD8_Treg","B_cells","NK_cells","NKT_cells","M1","M2","CD163","iDC","mDC","pDC","PanCKsingle_TIL", "PanCKsingle_NK","PanCKsingle_APC"))
PhenoAllNoCK$PhenoType <- factor(PhenoAllNoCK$PhenoType, levels = c("CD4_Eff","CD4_Treg","CD8_Eff","CD8_Treg","B_cells","NK_cells","NKT_cells","M1","M2","CD163","iDC","mDC","pDC"))
PhenoTIL$PhenoType <- factor(PhenoTIL$PhenoType, levels = c("CD4_Eff","CD4_Treg","CD8_Eff","CD8_Treg","B_cells","PanCKsingle_TIL"))
PhenoNK$PhenoType <- factor(PhenoNK$PhenoType, levels = c("NK_cells","NKT_cells","M1","M2","CD163","PanCKsingle_NK"))
PhenoAPC$PhenoType <- factor(PhenoAPC$PhenoType, levels = c("iDC","mDC","pDC","PanCKsingle_APC"))
fig12a <- ggplot(PhenoAllNoCK, aes(x = PhenoType, y = value, fill=giniGroup)) +
    geom_boxplot(outlier.shape = 16, outlier.size = 2, ) +
    theme_classic() +
    # coord_flip() +
    # scale_fill_npg() +
    theme(legend.position = "none") +
    stat_compare_means(paired = NULL, size=2) +
    facet_wrap(~Location, nrow = 3, strip.position = "left", scale="free") +
    scale_y_continuous(expand = c(0,0))


fig12b <- ggplot(PhenoAllNoCK, aes(x = Location, y = value, fill=giniGroup)) +
    geom_boxplot(outlier.shape = 16, outlier.size = 2, ) +
    theme_classic() +
    # coord_flip() +
    # scale_fill_npg() +
    theme(legend.position = "none") +
    stat_compare_means(paired = NULL, size=1.5) +
    facet_wrap(~PhenoType, nrow = 3, strip.position = "left", scale="free")

Fig13 Distance data

DistTIL <- read_excel("~/Project/TCR/Distance/BOMI2_dist.xlsx", sheet = "TIL_Gini")
DistTIL <- as.data.frame(DistTIL)
TIL_corrT <- rcorr(as.matrix(DistTIL[,c(5,27:56)]), type = "spearman")
write.csv(TIL_corrT$r, file = "~/Project/TCR/Distance/TIL_corr.csv")
write.csv(TIL_corrT$P, file = "~/Project/TCR/Distance/TIL_corr_Pvalue.csv")

# melt
TIL_corr_melt <- read_excel("~/Project/TCR/Distance/BOMI2_dist.xlsx", sheet = "TIL_Corr")
TIL_corr_melt[,"P_adjust"] <- p.adjust(TIL_corr_melt$`P-Value`,method = "BH")
TIL_corr_melt$label <- NULL
TIL_corr_melt.1d[TIL_corr_melt.1d$var1]
TIL_corr_melt[TIL_corr_melt$P_adjust <= 0.001,"label"] <- "***"
TIL_corr_melt[TIL_corr_melt$P_adjust > 0.001 & TIL_corr_melt$P_adjust <= 0.01,"label"] <- "**"
TIL_corr_melt[TIL_corr_melt$P_adjust > 0.01 & TIL_corr_melt$P_adjust <= 0.05,"label"] <- "*"
TIL_corr_melt$Correlation
ggplot(TIL_corr_melt, aes(var1, var2, fill = Correlation)) +
    geom_point(shape=21, colour = "black", size = 12)+
    theme_classic()+
    scale_fill_gradientn(colours = rev(brewer.pal(5, "Spectral")))+
    labs(title = "Correlation", x = "Outset", y = "End") +
    theme(axis.text = element_text(size = 10, colour = "black"), axis.title = element_text(size = 10),plot.title = element_text(size=15))+
    geom_text(aes(label = label), size = 5, colour = "black")

1D plot

TIL_corr_melt.1d <- read_excel("~/Project/TCR_Summary/Writing/SumSup.xlsx", sheet = "TIL_Corr_1D")
TIL_corr_melt.1d <- as.data.frame(TIL_corr_melt.1d)
# -0.122419365  0.138273993
#TIL_corr_melt.1d[TIL_corr_melt.1d$var1 == "CD4_Treg" & TIL_corr_melt.1d$var2 == "PanCKsingle", c("Correlation","P-Value")] <- c(-0.122419365, 0.138273993)
TIL_corr_melt.1d[,"P_adjust"] <- p.adjust(TIL_corr_melt.1d$`P-Value`,method = "BH")
TIL_corr_melt.1d[TIL_corr_melt.1d$P_adjust <= 0.001,"label"] <- "***"
TIL_corr_melt.1d[TIL_corr_melt.1d$P_adjust > 0.001 & TIL_corr_melt.1d$P_adjust <= 0.01,"label"] <- "**"
TIL_corr_melt.1d[TIL_corr_melt.1d$P_adjust > 0.01 & TIL_corr_melt.1d$P_adjust <= 0.05,"label"] <- "*"
ggplot(TIL_corr_melt.1d, aes(var2, var1, fill = Correlation)) +
    geom_point(shape=21, colour = "black", size = 12)+
    theme_classic()+
    scale_fill_gradientn(colours = rev(brewer.pal(5, "Spectral")))+
    labs(title = "Correlation", x = "Outset", y = "End") +
    theme(axis.text = element_text(size = 10, colour = "black"), axis.title = element_text(size = 10),plot.title = element_text(size=15))+
    geom_text(aes(label = label), size = 5, colour = "black")

Fig14 immunetherapy treated cohort

library(readxl)
itCohort <- read_excel("~/Project/TCR/ImmuneCohort/GSE126044_gini_ab.xlsx", 
    sheet = "Sheet3")
View(itCohort)

itCohort <- as.data.frame(itCohort)

print(fig14b_test)
Call: survfit(formula = Surv(`Progression free survival (month)`, Status) ~ 
    giniGroup, data = itCohort)

               n events median 0.95LCL 0.95UCL
giniGroup=High 5      3  13.83    13.5      NA
giniGroup=Low  4      4   2.87     1.1      NA
summary(fig14b_test)$table
               records n.max n.start events    rmean se(rmean)    median 0.95LCL 0.95UCL
giniGroup=High       5     5       5      3 14.02667 1.7040449 13.833333    13.5      NA
giniGroup=Low        4     4       4      4  2.60000 0.4980518  2.866667     1.1      NA

surv_median(fig14b_test)
Warning: `select_()` was deprecated in dplyr 0.7.0.
Please use `select()` instead.

Figure 15 Lymph nodes

Beta clone distance

GiniDist <- read.table("/Users/huiyu818/Project/TCR/TCRdist//cloneSummary/beta_tumor_dist_rank.txt")
GiniDist <- as.data.frame(GiniDist)
pheatmap(GiniDist,
         cluster_rows = F, cluster_cols = F,
         #cutree_cols = 3,
         color = colorRampPalette(brewer.pal(n = 7, name = "RdYlBu"))(100),
         fontsize = 5,
         show_colnames = T
)
# Load the annotation
GiniDist_anno <-  read_excel("~/Project/TCR/TCRdist/cloneSummary/beta_tumor.xlsx", sheet = "Distance_DF_2")
GiniDist_anno <- as.data.frame(GiniDist_anno)
rownames(GiniDist_anno) <- GiniDist_anno$clone_id_new
GiniDist_anno_color = list(
#  "GiniIndex" = colorRampPalette(brewer.pal(n = 9, name = "Reds"))(100),
  "Anti_virus" = c(Y = "#D45F51", N = "#B7D2E8"))

pheatmap(GiniDist,
         clustering_method = "ward.D2",
         clustering_distance_rows = "euclidean", clustering_distance_cols = "euclidean",
         color = colorRampPalette(brewer.pal(n = 7, name = "RdYlBu"))(100),
         annotation_col = GiniDist_anno["Anti_virus"],
         annotation_colors = GiniDist_anno_color,
         fontsize = 5,
         show_colnames = T
         )
pheatmap(t(ihcHeatT_tumor_norm2), clustering_method = "ward.D2",
                  clustering_distance_rows = "euclidean", clustering_distance_cols = "euclidean",
                  cutree_cols = 3,
                  #color = colorRampPalette(brewer.pal(n = 7, name = "YlGnBu"))(100),
                  annotation_col = ihcAnno,
                  annotation_colors = ihcAnno_color,
                  fontsize = 5,
                  show_colnames = F
                  )

Cancer testis antigens

CTA_list <- read_excel("~/Project/TCR_Summary/Writing/SumSup.xlsx", sheet = "CTA")

CTA_list <- as.data.frame(CTA_list)
Bomi2RC_tumor_norm <- read.csv("~/Project/Clinical/BOMI2/BOMI2_RNAseq_FPKM/RNASeq_counts_tumor_norm.txt", sep="\t")

CTA list 1 (all from database)

setnames(GiniClin_CTA_ori, old =  CTA_list[["Ensgid_1"]], new = CTA_list[["Gene_1"]])
Error in setnames(GiniClin_CTA_ori, old = CTA_list[["Ensgid_1"]], new = CTA_list[["Gene_1"]]) : 
  Items of 'old' not found in column names: [ENSG00000183461, ENSG00000204379, ENSG00000204382, ENSG00000204376, ENSG00000204375, ENSG00000221867, ENSG00000197172, ENSG00000137948, ENSG00000123584, ENSG00000183305, ...]. Consider skip_absent=TRUE.
GiniClin_CTA_ori[1,37]
[1] 2.098581
CTA_corr <- rcorr(as.matrix(GiniClin_CTA_ori[,c(5,37:132)]), type = "spearman")

write.csv(CTA_corr$r, file = "~/Project/TCR/CTA/ctaCor.csv")
write.csv(CTA_corr$P, file = "~/Project/TCR/CTA/ctaPvalue.csv")
CTA_corrT <- rename(CTA_corrT, c("...1"="GeneSymbol"))
Error in `rename()`:
! Can't rename columns that don't exist.
✖ Column `GeneSymbol` doesn't exist.
Backtrace:
 1. dplyr::rename(CTA_corrT, c(...1 = "GeneSymbol"))
 2. dplyr:::rename.data.frame(CTA_corrT, c(...1 = "GeneSymbol"))

CTA list 2 (noval list)

GiniClin_CTA_ori_2 <- merge(GiniClin_tumor, GiniClin_CTA_ori_2, by.x = "ID" ,by.y = "row.names")
setnames(GiniClin_CTA_ori_2, old =  CTA_list[["Ensgid_2"]], new = CTA_list[["Gene_2"]])
Error in setnames(GiniClin_CTA_ori_2, old = CTA_list[["Ensgid_2"]], new = CTA_list[["Gene_2"]]) : 
  NA in 'new' at positions [91, 92, 93, 94, 95, 96]
GiniClin_CTA_ori_2[3,37]
[1] 0.9198992
CTA_corr_2 <- rcorr(as.matrix(GiniClin_CTA_ori_2[,c(5,37:126)]), type = "spearman")

write.csv(CTA_corr_2$r, file = "~/Project/TCR/CTA/ctaCor_list2.csv")
write.csv(CTA_corr_2$P, file = "~/Project/TCR/CTA/ctaPvalue_list2.csv")

<!-- rnb-source-end -->

<!-- rnb-output-begin eyJkYXRhIjoiRXJyb3I6IGF0dGVtcHQgdG8gdXNlIHplcm8tbGVuZ3RoIHZhcmlhYmxlIG5hbWVcbiJ9 -->

Error: attempt to use zero-length variable name




<!-- rnb-output-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->



<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuQ1RBX2NvcnJUXzIgPC0gcmVhZF9leGNlbChcIn4vUHJvamVjdC9UQ1IvQ1RBL0NUQS54bHN4XCIsIHNoZWV0ID0gXCJHZW5lTGlzdDJcIilcbkNUQV9jb3JyVF8yIDwtIGFzLmRhdGEuZnJhbWUoQ1RBX2NvcnJUXzIpXG5cbkNUQV9jb3JyVF8yWyxcInBhZGpcIl0gPC0gcC5hZGp1c3QoQ1RBX2NvcnJUXzIkUHZhbHVlLG1ldGhvZCA9IFwiQkhcIilcbmBgYCJ9 -->

```r
CTA_corrT_2 <- read_excel("~/Project/TCR/CTA/CTA.xlsx", sheet = "GeneList2")
CTA_corrT_2 <- as.data.frame(CTA_corrT_2)

CTA_corrT_2[,"padj"] <- p.adjust(CTA_corrT_2$Pvalue,method = "BH")

Vocanol plot

ggplot(data = diffGene, aes(x = log2FoldChange, y = -log10(padj), color = sign)) + 
  geom_point(size = 1) +  #Create scatter plot
  scale_color_manual(values = c('red', 'gray', 'green'), limits = c('UP', 'none', 'DOWN')) +  #Set the color
  labs(x = 'log2 Fold Change', y = '-log10 adjust p-value', title = 'High clonality vs Low clonality', color = '') +  #Set the labels
  theme(plot.title = element_text(hjust = 0.5, size = 14), panel.grid = element_blank(), #Change the them and grid lines
  panel.background = element_rect(color = 'black', fill = 'transparent'), 
  legend.key = element_rect(fill = 'transparent')) +
  geom_vline(xintercept = c(-1, 1), lty = 3, color = 'black') +  #Add threshold line
  geom_hline(yintercept = 2, lty = 3, color = 'black') +
  xlim(-12, 12) + ylim(0, 35) + #Set the curve boundary
  geom_text_repel(
    data = diffGene,
    aes(label = label),
    size = 3, segment.color = "blue", show.legned = FALSE,
    point.padding = unit(0.8, "lines")
  )

ISS plot

library(dplyr)

ISS_dot_data <- ISS_dot_data %>%
  group_by(Sample) %>%
  mutate(Normalized_Clone_fraction = scale(Clone_fraction),  # Normalizing clone fraction
         Normalized_Clone_mean = scale(Clone_mean)) %>%  # Normalizing clone mean
  ungroup()
ggplot(ISS_dot_data, aes(Clone, EPCAM_CDH1_anno)) +
  geom_point(aes(size=Normalized_Clone_fraction, color = Normalized_Clone_mean))+
  facet_wrap(~ Sample, scales = "free_x", drop = TRUE) +
  theme_bw()+
  theme(panel.grid.major = element_blank(),  # Remove major grid lines
        panel.grid.minor = element_blank()) + # Remove minor grid lines
  scale_size(range = c(1, 10)) +
  scale_color_gradientn(colors = rev(brewer.pal(5, "Spectral")))+
  labs(title = "Bubble plot grouped by sample", x = "Clone", y = "EPCAM_CDH1 annotation") +
  theme(axis.text.x = element_text(size = 10, colour = "black", angle = 45), axis.title = element_text(size = 10),plot.title = element_text(size=15))

ggplot(ISS_dot_data_L766, aes(Clone, EPCAM_CDH1_anno)) +
  geom_point(aes(size=Clone_fraction, color = Clone_mean))+
  theme_bw()+
  theme(panel.grid.major = element_blank(),  # Remove major grid lines
        panel.grid.minor = element_blank()) + # Remove minor grid lines
  scale_color_gradientn(colors = rev(brewer.pal(5, "Spectral")))+
  labs(title = "Bubble plot grouped by sample", x = "Clone", y = "EPCAM_CDH1 annotation") +
  theme(axis.text.x = element_text(size = 10, colour = "black", angle = 45), axis.title = element_text(size = 10),plot.title = element_text(size=15))

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KGNsdXN0ZXJQcm9maWxlcikKCmxpYnJhcnkoR09wbG90KQpsaWJyYXJ5KERPU0UpCgpsaWJyYXJ5KHRvcEdPKQpsaWJyYXJ5KGNpcmNsaXplKQpsaWJyYXJ5KCJwaGVhdG1hcCIpCgpsaWJyYXJ5KCJnZ3NjaSIpCmxpYnJhcnkoImdncGxvdDIiKQpsaWJyYXJ5KCJncmlkRXh0cmEiKQoKbGlicmFyeSgic3Vydml2YWwiKQpsaWJyYXJ5KCJzdXJ2bWluZXIiKQoKbGlicmFyeShnZ3B1YnIpCmxpYnJhcnkocnN0cG0yKQpsaWJyYXJ5KGNvcnJwbG90KQpsaWJyYXJ5KEhtaXNjKQoKbGlicmFyeShjb3dwbG90KQpsaWJyYXJ5KHJlc2hhcGUpCgpsaWJyYXJ5KGdnYnJlYWspCmxpYnJhcnkoZ2dyZXBlbCkKYGBgCgoKYGBge3J9CkdpbmlDbGluIDwtIHJlYWRfZXhjZWwoIn4vUHJvamVjdC9UQ1JfU3VtbWFyeS9Xcml0aW5nL1N1bVN1cC54bHN4Iiwgc2hlZXQgPSAiR2luaV9DbGluaWMiKQoKR2luaUNsaW4gPC0gYXMuZGF0YS5mcmFtZShHaW5pQ2xpbiwgcm93Lm5hbWVzID0gR2luaUNsaW4kSUQpCgpgYGAKCiMgRmlndXJlIDEKCmBgYHtyfQpmMWEgPC0gZ2dwbG90KEdpbmlDbGluLCBhZXMoeD1HaW5pSW5kZXgpKSArCiAgZ2VvbV9oaXN0b2dyYW0oY29sb3VyID0gImJsYWNrIiwgZmlsbD0iIzRkYmJkNWZmIiwgYmlucyA9IDUwKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSkgKwogIGxhYnModGl0bGUgPSAiR2luaV9kaXN0cmlidXRpb24iLCB5ID0gIlBhdGllbnQgY291bnQiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSwgbGltaXRzID0gYygwLCAwLjgpKSArIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsMCksIGxpbWl0cyA9IGMoMCwyNSkpCgpmMWEKYGBgCgpgYGB7cn0KcXFub3JtKEdpbmlDbGluX3R1bW9yJEdpbmlJbmRleCwgeWxhYiA9ICdHaW5pSW5kZXgnKQpxcWxpbmUoR2luaUNsaW5fdHVtb3IkR2luaUluZGV4KSAjIOWinuWKoOi2i+WKv+ebtOe6v++8jOWIqeS6juavlOi+gwpgYGAKCmBgYHtyfQojIEgwIGlzIHRoYXQgdGhlIGRhdGEgZml0IG5vcm1hbCBkaXN0cmlidXRpb24Kc2hhcGlyby50ZXN0KEdpbmlDbGluX3R1bW9yJEdpbmlJbmRleCkKYGBgCgoKCmBgYHtyfQpHaW5pQ2xpbl9BY1NxIDwtIEdpbmlDbGluW0dpbmlDbGluJGhpc3RvbG9neV9IYW5zX0JfV0hPXzIwMTUgJWluJSBjKCJBQyIsIlNxQ0MiKSwgXQoKZjFhXzIgPC0gZ2dwbG90KEdpbmlDbGluX0FjU3EsIGFlcyh4PUdpbmlJbmRleCwgZmlsbCA9IGhpc3RvbG9neV9IYW5zX0JfV0hPXzIwMTUpKSArCiAgZ2VvbV9oaXN0b2dyYW0oY29sb3IgPSAiYmxhY2siLCBwb3NpdGlvbiA9ICJpZGVudGl0eSIsIGJpbnMgPSA1MCwgc2l6ZSA9IDAuMykgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUoYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgY29sb3VyID0gImJsYWNrIiksIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC44LDAuOCkpICsKICBsYWJzKHRpdGxlID0gIkdpbmlfZGlzdHJpYnV0aW9uIiwgZmlsbCA9ICJIaXN0b2xvZ3kiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYWxwaGEoYygiI0Y4NzY2RCIsICIjMDBCRkM0IiksIDAuNzUpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSwgbGltaXRzID0gYygwLDAuODUpKSArIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsMCksIGxpbWl0cyA9IGMoMCwxNyksIGJyZWFrcyA9IGMoc2VxKDAsMTUsNSkpKQoKZjFhXzIKYGBgCgoKYGBge3J9CkdpbmlDbGluX3R1bW9yIDwtIHJlYWRfZXhjZWwoIn4vUHJvamVjdC9UQ1JfU3VtbWFyeS9Xcml0aW5nL1N1bVN1cC54bHN4Iiwgc2hlZXQgPSAiR2luaV9DbGluaWNfdHVtb3IiKQoKR2luaUNsaW5fdHVtb3IgPC0gYXMuZGF0YS5mcmFtZShHaW5pQ2xpbl90dW1vciwgcm93Lm5hbWVzID0gR2luaUNsaW5fdHVtb3IkSUQpCmBgYAoKCgoKIyMgQm94IHBsb3QKYGBge3J9CiMgQWdlIGdyb3VwCkdpbmlDbGluX3R1bW9yW0dpbmlDbGluX3R1bW9yJGFnZSA+PSA3MCAsImFnZUdyb3VwIl0gPC0gIkFib3ZlIDcwIgpHaW5pQ2xpbl90dW1vcltHaW5pQ2xpbl90dW1vciRhZ2UgPCA3MCAsImFnZUdyb3VwIl0gPC0gIlVuZGVyIDcwIgoKIyBmMWJfMSA8LSBnZ3Bsb3QoR2luaUNsaW5fdHVtb3IsIGFlcyh4ID0gYWdlR3JvdXAsIHkgPSBHaW5pSW5kZXgsIGZpbGw9YWdlR3JvdXApKSArCgpmMWJfMSA8LSBnZ3Bsb3QoR2luaUNsaW5fdHVtb3IsIGFlcyh4ID0gYWdlR3JvdXAsIHkgPSBHaW5pSW5kZXgsIGZpbGw9YWdlR3JvdXApKSArCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3VyID0gImJsYWNrIiwgb3V0bGllci5zaGFwZSA9IDE2LCBvdXRsaWVyLnNpemUgPSAyLCBjb2xvdXIgPSAiYmxhY2siLCBub3RjaCA9IEZBTFNFKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICAjY29vcmRfZmxpcCgpICsKICAjc2NhbGVfY29sb3JfbnBnKCkgKwogIGxhYnModGl0bGUgPSAiQWdlIiwgeCA9ICJBZ2UiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBOVUxMKQoKZjFiXzEKYGBgCgpgYGB7cn0KR2luaUNsaW5fdHVtb3JbR2luaUNsaW5fdHVtb3IkYHN0YWRpdW0gbnVtYmVycyBlZHQgOCAoUE1JKWAgPj0gNSAsInN0YWdlR3JvdXAiXSA8LSAiSGlnaCBzdGFnZSIKR2luaUNsaW5fdHVtb3JbR2luaUNsaW5fdHVtb3IkYHN0YWRpdW0gbnVtYmVycyBlZHQgOCAoUE1JKWAgPCA1ICwic3RhZ2VHcm91cCJdIDwtICJMb3cgc3RhZ2UiCgpmMWJfMiA8LSBnZ3Bsb3QoR2luaUNsaW5fdHVtb3IsIGFlcyh4ID0gc3RhZ2VHcm91cCwgeSA9IEdpbmlJbmRleCwgZmlsbD1zdGFnZUdyb3VwKSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLmNvbG91ciA9ICJibGFjayIsIG91dGxpZXIuc2hhcGUgPSAxNiwgb3V0bGllci5zaXplID0gMiwgY29sb3VyID0gImJsYWNrIikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgIyBjb29yZF9mbGlwKCkgKwogICMgc2NhbGVfY29sb3JfbnBnKCkgKwogIGxhYnModGl0bGUgPSAiU3RhZ2UiLCB4ID0gIlN0YWdlIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gTlVMTCkKCmYxYl8yCmBgYAoKCmBgYHtyfQojIGhpc3RvbG9neQpmMWJfMyA8LSBnZ3Bsb3QoR2luaUNsaW5fdHVtb3IsIGFlcyh4ID0gaGlzdG9sb2d5X0hhbnNfQl9XSE9fMjAxNSwgeSA9IEdpbmlJbmRleCwgZmlsbD1oaXN0b2xvZ3lfSGFuc19CX1dIT18yMDE1KSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLmNvbG91ciA9ICJibGFjayIsIG91dGxpZXIuc2hhcGUgPSAxNiwgb3V0bGllci5zaXplID0gMiwgY29sb3VyID0gImJsYWNrIikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgI2Nvb3JkX2ZsaXAoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0Y4NzY2RCIsICIjOTk5OTk5IiwgIiMwMEJGN0QiLCIjMDBCMEY2IiwiI0EzQTUwMCIsICIjMDBCRkM0IikpICsKICBsYWJzKHRpdGxlID0gIkhpc3RvbG9neSIsIHggPSAiSGlzdG9sb2d5IikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gTlVMTCkKCmYxYl8zCmBgYAoKYGBge3J9CkdpbmlDbGluX3R1bW9yW0dpbmlDbGluX3R1bW9yJGdlbmRlciA9PSAiTSIgLCJnZW5kZXIiXSA8LSAiTWFsZSIKR2luaUNsaW5fdHVtb3JbR2luaUNsaW5fdHVtb3IkZ2VuZGVyID09ICJGIiAsImdlbmRlciJdIDwtICJGZW1hbGUiCgpmMWJfNCA8LSBnZ3Bsb3QoR2luaUNsaW5fdHVtb3IsIGFlcyh4ID0gZ2VuZGVyLCB5ID0gR2luaUluZGV4LCBmaWxsPWdlbmRlcikpICsKICBnZW9tX2JveHBsb3Qob3V0bGllci5jb2xvdXIgPSAiYmxhY2siLCBvdXRsaWVyLnNoYXBlID0gMTYsIG91dGxpZXIuc2l6ZSA9IDIsIGNvbG91ciA9ICJibGFjayIpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogICMgY29vcmRfZmxpcCgpICsKICAjIHNjYWxlX2ZpbGxfbnBnKCkgKwogIGxhYnModGl0bGUgPSAiR2VuZGVyIiwgeCA9ICJTZXgiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBOVUxMKQoKZjFiXzQKCmBgYAoKYGBge3J9CiMgU21va2UKR2luaUNsaW5fdHVtb3JbR2luaUNsaW5fdHVtb3Ikc21va2UgPT0gIk4iICwic21va2UiXSA8LSAiTmV2ZXIgc21va2UiCkdpbmlDbGluX3R1bW9yW0dpbmlDbGluX3R1bW9yJHNtb2tlID09ICJDIiAsInNtb2tlIl0gPC0gIkN1cnJlbnQgc21va2UiCkdpbmlDbGluX3R1bW9yW0dpbmlDbGluX3R1bW9yJHNtb2tlID09ICJGIiAsInNtb2tlIl0gPC0gIkZvcm1lciBzbW9rZSIKCmYxYl81IDwtIGdncGxvdChHaW5pQ2xpbl90dW1vciwgYWVzKHggPSBzbW9rZSwgeSA9IEdpbmlJbmRleCwgZmlsbD1zbW9rZSkpICsKICBnZW9tX2JveHBsb3Qob3V0bGllci5jb2xvdXIgPSAiYmxhY2siLCBvdXRsaWVyLnNoYXBlID0gMTYsIG91dGxpZXIuc2l6ZSA9IDIsIGNvbG91ciA9ICJibGFjayIpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogICMgY29vcmRfZmxpcCgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjRjg3NjZEIiwgIiMwMEJGQzQiLCAiIzk5OTk5OSIpKSArCiAgbGFicyh0aXRsZSA9ICJTbW9rZSIsIHggPSAiU21va2UiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBOVUxMKQoKZjFiXzUKYGBgCgpgYGB7cn0KIyBTbW9rZQpHaW5pQ2xpbl90dW1vcltHaW5pQ2xpbl90dW1vciRzbW9rZSA9PSAiTmV2ZXIgc21va2UiICwic21va2VfMiJdIDwtICJOb24gc21va2VyIgpHaW5pQ2xpbl90dW1vcltHaW5pQ2xpbl90dW1vciRzbW9rZSA9PSAiQ3VycmVudCBzbW9rZSIgfCBHaW5pQ2xpbl90dW1vciRzbW9rZSA9PSAiRm9ybWVyIHNtb2tlIiwic21va2VfMiJdIDwtICIgU21va2VyIgoKZjFiXzVfMiA8LSBnZ3Bsb3QoR2luaUNsaW5fdHVtb3IsIGFlcyh4ID0gc21va2VfMiwgeSA9IEdpbmlJbmRleCwgZmlsbD1zbW9rZV8yKSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLmNvbG91ciA9ICJibGFjayIsIG91dGxpZXIuc2hhcGUgPSAxNiwgb3V0bGllci5zaXplID0gMiwgY29sb3VyID0gImJsYWNrIikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgIyBjb29yZF9mbGlwKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNGODc2NkQiLCAiIzAwQkZDNCIpKSArCiAgbGFicyh0aXRsZSA9ICJTbW9rZSIsIHggPSAiU21va2UiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSkKCmYxYl81XzIKYGBgCgpgYGB7cn0KIyBXSE8gUFMKR2luaUNsaW5fdHVtb3JbR2luaUNsaW5fdHVtb3IkV0hPX1BTID09IDAgLCJXSE9fUFNfZ3JvdXAiXSA8LSAwCkdpbmlDbGluX3R1bW9yW0dpbmlDbGluX3R1bW9yJFdIT19QUyA+IDAgLCJXSE9fUFNfZ3JvdXAiXSA8LSAiPiAwIgoKZjFiXzYgPC0gZ2dwbG90KEdpbmlDbGluX3R1bW9yLCBhZXMoeCA9IFdIT19QU19ncm91cCwgeSA9IEdpbmlJbmRleCwgZmlsbD1XSE9fUFNfZ3JvdXApKSArCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3VyID0gImJsYWNrIiwgb3V0bGllci5zaGFwZSA9IDE2LCBvdXRsaWVyLnNpemUgPSAyLCBjb2xvdXIgPSAiYmxhY2siKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICAjIGNvb3JkX2ZsaXAoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0Y4NzY2RCIsICIjMDBCRkM0IikpICsKICBsYWJzKHRpdGxlID0gIldITyBwZXJmb3JtYW5jZSBzdGF0dXMiLCB4ID0gIldITyBwZXJmb3JtYW5jZSByYW5rIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UpCgpmMWJfNgpgYGAKCiMjIyBBQy9TcUNDCmBgYHtyfQpnZ3Bsb3QoR2luaUNsaW5fdHVtb3JbR2luaUNsaW5fdHVtb3IkaGlzdG9sb2d5X0hhbnNfQl9XSE9fMjAxNSA9PSAiQUMiLCBdLCBhZXMoeCA9IHN0YWdlR3JvdXAsIHkgPSBHaW5pSW5kZXgsIGZpbGw9c3RhZ2VHcm91cCkpICsKICBnZW9tX2JveHBsb3Qob3V0bGllci5jb2xvdXIgPSAiYmxhY2siLCBvdXRsaWVyLnNoYXBlID0gMTYsIG91dGxpZXIuc2l6ZSA9IDIsIGNvbG91ciA9ICJibGFjayIpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogICMgY29vcmRfZmxpcCgpICsKICAjIHNjYWxlX2NvbG9yX25wZygpICsKICBsYWJzKHRpdGxlID0gIlN0YWdlIiwgeCA9ICJTdGFnZSIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIiksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MjApKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IE5VTEwpCmBgYAoKYGBge3J9CmdncGxvdChHaW5pQ2xpbl90dW1vcltHaW5pQ2xpbl90dW1vciRoaXN0b2xvZ3lfSGFuc19CX1dIT18yMDE1ID09ICJTcUNDIiwgXSwgYWVzKHggPSBzdGFnZUdyb3VwLCB5ID0gR2luaUluZGV4LCBmaWxsPXN0YWdlR3JvdXApKSArCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3VyID0gImJsYWNrIiwgb3V0bGllci5zaGFwZSA9IDE2LCBvdXRsaWVyLnNpemUgPSAyLCBjb2xvdXIgPSAiYmxhY2siKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICAjIGNvb3JkX2ZsaXAoKSArCiAgIyBzY2FsZV9jb2xvcl9ucGcoKSArCiAgbGFicyh0aXRsZSA9ICJTdGFnZSIsIHggPSAiU3RhZ2UiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBOVUxMKQpgYGAKCmBgYHtyfQpnZ3Bsb3QoR2luaUNsaW5fdHVtb3JbR2luaUNsaW5fdHVtb3IkaGlzdG9sb2d5X0hhbnNfQl9XSE9fMjAxNSA9PSAiQUMiLCBdLCBhZXMoeCA9IFdIT19QU19ncm91cCwgeSA9IEdpbmlJbmRleCwgZmlsbD1XSE9fUFNfZ3JvdXApKSArCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3VyID0gImJsYWNrIiwgb3V0bGllci5zaGFwZSA9IDE2LCBvdXRsaWVyLnNpemUgPSAyLCBjb2xvdXIgPSAiYmxhY2siKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICAjIGNvb3JkX2ZsaXAoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0Y4NzY2RCIsICIjMDBCRkM0IikpICsKICBsYWJzKHRpdGxlID0gIldITyBwZXJmb3JtYW5jZSBzdGF0dXMiLCB4ID0gIldITyBwZXJmb3JtYW5jZSByYW5rIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UpCmBgYAoKYGBge3J9CmdncGxvdChHaW5pQ2xpbl90dW1vcltHaW5pQ2xpbl90dW1vciRoaXN0b2xvZ3lfSGFuc19CX1dIT18yMDE1ID09ICJTcUNDIiwgXSwgYWVzKHggPSBXSE9fUFNfZ3JvdXAsIHkgPSBHaW5pSW5kZXgsIGZpbGw9V0hPX1BTX2dyb3VwKSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLmNvbG91ciA9ICJibGFjayIsIG91dGxpZXIuc2hhcGUgPSAxNiwgb3V0bGllci5zaXplID0gMiwgY29sb3VyID0gImJsYWNrIikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgIyBjb29yZF9mbGlwKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNGODc2NkQiLCAiIzAwQkZDNCIpKSArCiAgbGFicyh0aXRsZSA9ICJXSE8gcGVyZm9ybWFuY2Ugc3RhdHVzIiwgeCA9ICJXSE8gcGVyZm9ybWFuY2UgcmFuayIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIiksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MjApKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFKQpgYGAKCgoKCiMgRmlndXJlIDIKYGBge3J9CmxpYnJhcnkoInN1cnZpdmFsIikKbGlicmFyeSgic3Vydm1pbmVyIikKYGBgCgojIyBGaWd1cmUyQTogS00gcGxvdAoKIyMjIEFsbCBwYXRpZW50CgoKYGBge3J9CkdpbmlDbGluX3R1bW9yW0dpbmlDbGluX3R1bW9yJEdpbmlJbmRleCA+PSAwLjI1NDMxLCAiZ2luaUdyb3VwIl0gPC0gIkFib3ZlIG1lZGlhbiIKR2luaUNsaW5fdHVtb3JbR2luaUNsaW5fdHVtb3IkR2luaUluZGV4IDwgMC4yNTQzMSwgImdpbmlHcm91cCJdIDwtICJVbmRlciBtZWRpYW4iCkdpbmlDbGluX3R1bW9yJGdpbmlHcm91cCA9IGZhY3RvcihHaW5pQ2xpbl90dW1vciRnaW5pR3JvdXAsIGxldmVscyA9IGMoIkFib3ZlIG1lZGlhbiIsICJVbmRlciBtZWRpYW4iKSkKR2luaUNsaW5fdHVtb3JbJ0w0ODFUJywgJ3N0YXR1c181X3llYXJzX3RydW5rXzIwMTkwMzI5J10gPSAxCkdpbmlDbGluX3R1bW9yMiA8LSBHaW5pQ2xpbl90dW1vclshR2luaUNsaW5fdHVtb3IkSUQgPT0gJ0w1ODRUJyxdCmBgYAoKYGBge3J9CiMgY29uc3RydWN0IHRoZSBvYmplY3QKZmlnMnRlc3QgPC0gc3VydmZpdChTdXJ2KE9TX3llYXJzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjksIHN0YXR1c181X3llYXJzX3RydW5rXzIwMTkwMzI5KSB+IGdpbmlHcm91cCwgZGF0YSA9IEdpbmlDbGluX3R1bW9yKQoKcHJpbnQoZmlnMnRlc3QpCgpzdW1tYXJ5KGZpZzJ0ZXN0KSR0YWJsZQoKYGBgCgpgYGB7cn0KZmlnMmFfYWxsIDwtIGdnc3VydnBsb3QoZmlnMnRlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgIHB2YWwgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gYygiI2U2NGIzNSIsICIjNGRiYmQ1IiksCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrLnRpbWUuYnkgPSAxLAogICAgICAgICAgICAgICAgICAgICAgICBnZ3RoZW1lID0gdGhlbWVfY2xhc3NpYygpLAogICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQubGFicyA9IGMoIkFib3ZlIG1lZGlhbiIsICJVbmRlciBtZWRpYW4iKSwKICAgICAgICAgICAgICAgICAgICAgICAgcmlzay50YWJsZSA9ICJhYnNfcGN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgcmlzay50YWJsZS55LnRleHQgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgeGxhYiA9ICJUaW1lICh5ZWFycykiLAogICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJnaW5pU3VydiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHhsaW0gPSBjKDAsNS4yKSwKICAgICAgICAgICAgICAgICAgICAgICAgYXhlcy5vZmZzZXQgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgcmlzay50YWJsZS5mb250c2l6ZSA9IDIuNSwKICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kID0gYygwLjksMC45KSwKICAgICAgICAgICAgICAgICAgICAgICAgcmlzay50YWJsZS50aXRsZSA9ICJOdW1iZXIgYXQgcmlzayBieSB0aW1lOiBuICglKSIsCiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnQubWFpbiA9IGMoKSkKCgpmaWcyYV9hbGwKYGBgCgpgYGB7cn0KZmlnMmFfY29udGludWUuY294IDwtIGNveHBoKFN1cnYoT1NfeWVhcnNfNV95ZWFyc190cnVua18yMDE5MDMyOSwgc3RhdHVzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjkpIH4gR2luaUluZGV4LCBkYXRhID0gR2luaUNsaW5fdHVtb3IpCmZpZzJhX2NvbnRpbnVlLmNveApgYGAKCmBgYHtyfQpnZ3N1cnZwbG90KHN1cnZmaXQoZmlnMmFfY29udGludWUuY294LCBkYXRhPUdpbmlDbGluX3R1bW9yKSwgY29sb3IgPSAiIzJFOUZERiIsZ2d0aGVtZSA9IHRoZW1lX21pbmltYWwoKSkKYGBgCgoKIyMjIyBUaW1lIHNwbGl0IHN1cnYKYGBge3J9CkdpbmlDbGluX3R1bW9yW0dpbmlDbGluX3R1bW9yJGdpbmlHcm91cCA9PSAiQWJvdmUgbWVkaWFuIiwgImdpbmlHcm91cF9uciJdIDwtIDEKR2luaUNsaW5fdHVtb3JbR2luaUNsaW5fdHVtb3IkZ2luaUdyb3VwID09ICJVbmRlciBtZWRpYW4iLCAiZ2luaUdyb3VwX25yIl0gPC0gMAoKZmlnMl90aW1lc3BsIDwtIHN1cnZTcGxpdChTdXJ2KE9TX3llYXJzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjksIHN0YXR1c181X3llYXJzX3RydW5rXzIwMTkwMzI5ID09IDEpIH4gLiwgZGF0YT1HaW5pQ2xpbl90dW1vcjIsIGN1dD1jKDIpLCBlcGlzb2RlID0gInRncm91cCIpCgpmaWcyX3RpbWVzcGwuY294IDwtIGNveHBoKFN1cnYodHN0YXJ0LCBPU195ZWFyc181X3llYXJzX3RydW5rXzIwMTkwMzI5LCBldmVudD09MSkgfiBnaW5pR3JvdXBfbnI6c3RyYXRhKHRncm91cCksIGRhdGE9ZmlnMl90aW1lc3BsLCB0aWVzPSJlZnJvbiIpCnN1bW1hcnkoZmlnMl90aW1lc3BsLmNveCkKCmBgYAoKYGBge3J9CmNveC56cGgoZmlnMl90aW1lc3BsLmNveCkKYGBgCgpgYGB7cn0KZmlnMl9tb2RfdHZjIDwtIHN0cG0yKFN1cnYoT1NfeWVhcnNfNV95ZWFyc190cnVua18yMDE5MDMyOSwgc3RhdHVzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjkgPT0gMSkgfiBnaW5pR3JvdXBfbnIsIGRhdGEgPSBHaW5pQ2xpbl90dW1vciwgZGY9MywgdHZjPWxpc3QoZ2luaUdyb3VwX25yPTEpKQoKcGxvdChmaWcyX21vZF90dmMsIG5ld2RhdGEgPSBkYXRhLmZyYW1lKGdpbmlHcm91cF9uciA9IDApLCB0eXBlID0gImhhemFyZCIsICB4bGltPWMoMC41LDUpLCB5bGltPWMoMCwwLjIpLCB5bGFiID0gIkhhemFyZCIsIHhsYWIgPSAiVGltZSIsIGx3ZCA9IDIsIGNpID0gRkFMU0UpCnBsb3QoZmlnMl9tb2RfdHZjLCBuZXdkYXRhID0gZGF0YS5mcmFtZShnaW5pR3JvdXBfbnIgPSAxKSwgdHlwZSA9ICJoYXphcmQiLCBsaW5lLmNvbD0yLCBjaT1GQUxTRSwgbHdkID0gMiwgYWRkPVRSVUUpCmBgYAoKIyMjIyBDYWxjdWxhdGUgYmVzdCBjdXRvZmYKYGBge3J9CmZpZzIuY3V0IDwtIHN1cnZfY3V0cG9pbnQoR2luaUNsaW5fdHVtb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZSA9ICJPU195ZWFyc181X3llYXJzX3RydW5rXzIwMTkwMzI5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudCA9ICJzdGF0dXNfNV95ZWFyc190cnVua18yMDE5MDMyOSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVzID0gIkdpbmlJbmRleCIpCnN1bW1hcnkoZmlnMi5jdXQpCmBgYApgYGB7cn0KcGxvdChmaWcyLmN1dCwgIkdpbmlJbmRleCIsIHBhbGV0dGUgPSAibnBnIikKYGBgCmBgYHtyfQpmaWcyLmN1dC5jYXQgPC0gc3Vydl9jYXRlZ29yaXplKGZpZzIuY3V0KQpmaWcyLmN1dC5maXQgPC0gc3VydmZpdChTdXJ2KE9TX3llYXJzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjksIHN0YXR1c181X3llYXJzX3RydW5rXzIwMTkwMzI5KSB+IEdpbmlJbmRleCwgZGF0YSA9IGZpZzIuY3V0LmNhdCkKCmdnc3VydnBsb3QoZmlnMi5jdXQuZml0LAogICAgICAgICAgIGRhdGEgPSBmaWcyLmN1dC5jYXQsCiAgICAgICAgICAgcmlzay50YWJsZSA9IFRSVUUsCiAgICAgICAgICAgcHZhbCA9IFQpCmBgYAoKCiMjIyMgQ2FsY3VsYXRlIEFDIGFuZCBTcUNDCgpgYGB7cn0KIyBBQwpmaWcyLmN1dF9BQyA8LSBzdXJ2X2N1dHBvaW50KEdpbmlDbGluX3R1bW9yX0FjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWUgPSAiT1NfeWVhcnNfNV95ZWFyc190cnVua18yMDE5MDMyOSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQgPSAic3RhdHVzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlcyA9ICJHaW5pSW5kZXgiKQpzdW1tYXJ5KGZpZzIuY3V0X0FDKQpgYGAKYGBge3J9CnBsb3QoZmlnMi5jdXRfQUMsICJHaW5pSW5kZXgiLCBwYWxldHRlID0gIm5wZyIpCmBgYApgYGB7cn0KZmlnMi5jdXRfQUMuY2F0IDwtIHN1cnZfY2F0ZWdvcml6ZShmaWcyLmN1dF9BQykKZmlnMi5jdXRfQUMuZml0IDwtIHN1cnZmaXQoU3VydihPU195ZWFyc181X3llYXJzX3RydW5rXzIwMTkwMzI5LCBzdGF0dXNfNV95ZWFyc190cnVua18yMDE5MDMyOSkgfiBHaW5pSW5kZXgsIGRhdGEgPSBmaWcyLmN1dF9BQy5jYXQpCgpnZ3N1cnZwbG90KGZpZzIuY3V0X0FDLmZpdCwKICAgICAgICAgICBkYXRhID0gZmlnMi5jdXQuY2F0LAogICAgICAgICAgIHJpc2sudGFibGUgPSBUUlVFLAogICAgICAgICAgIHB2YWwgPSBUKQpgYGAKCgojIyMjIEtNIHdpdGhvdXQgY2Vuc29yaW5nCmBgYHtyfQpmaWcyX05vQ2Vuc29yX3Rlc3QgPC0gc3VydmZpdChTdXJ2KE9TX3llYXJzXzIwMTkwMzI5LCBzdGF0dXNfb3V0XzIwMTkwMzI5KSB+IGdpbmlHcm91cCwgZGF0YSA9IEdpbmlDbGluX3R1bW9yKQoKcHJpbnQoZmlnMl9Ob0NlbnNvcl90ZXN0KQoKc3VtbWFyeShmaWcyX05vQ2Vuc29yX3Rlc3QpJHRhYmxlCmBgYAoKCgpgYGB7cn0KZmlnMl9Ob0NlbnNvciA8LSBnZ3N1cnZwbG90KGZpZzJfTm9DZW5zb3JfdGVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgcHZhbCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjZTY0YjM1IiwgIiM0ZGJiZDUiKSwKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsudGltZS5ieSA9IDIsCiAgICAgICAgICAgICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9jbGFzc2ljKCksCiAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC5sYWJzID0gYygiQWJvdmUgbWVkaWFuIiwgIlVuZGVyIG1lZGlhbiIpLAogICAgICAgICAgICAgICAgICAgICAgICByaXNrLnRhYmxlID0gImFic19wY3QiLAogICAgICAgICAgICAgICAgICAgICAgICByaXNrLnRhYmxlLnkudGV4dCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICB4bGFiID0gIlRpbWUgKHllYXJzKSIsCiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlID0gImdpbmlTdXJ2X3dpdGhvdXRfY2Vuc29yaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgYXhlcy5vZmZzZXQgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgcmlzay50YWJsZS5mb250c2l6ZSA9IDIuNSwKICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kID0gYygwLjksMC45KSwKICAgICAgICAgICAgICAgICAgICAgICAgcmlzay50YWJsZS50aXRsZSA9ICJOdW1iZXIgYXQgcmlzayBieSB0aW1lOiBuICglKSIsCiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnQubWFpbiA9IGMoKSkKCmZpZzJfTm9DZW5zb3IKYGBgCgoKYGBge3J9CmZpZzJfTm9DZW5zb3IuY3V0IDwtIHN1cnZfY3V0cG9pbnQoR2luaUNsaW5fdHVtb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZSA9ICJPU195ZWFyc18yMDE5MDMyOSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQgPSAic3RhdHVzX291dF8yMDE5MDMyOSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVzID0gIkdpbmlJbmRleCIpCnN1bW1hcnkoZmlnMl9Ob0NlbnNvci5jdXQpCmBgYAoKYGBge3J9CnBsb3QoZmlnMl9Ob0NlbnNvci5jdXQsICJHaW5pSW5kZXgiLCBwYWxldHRlID0gIm5wZyIpCmBgYApgYGB7cn0KZmlnMl9Ob0NlbnNvci5jdXQuY2F0IDwtIHN1cnZfY2F0ZWdvcml6ZShmaWcyX05vQ2Vuc29yLmN1dCkKZmlnMl9Ob0NlbnNvci5jdXQuZml0IDwtIHN1cnZmaXQoU3VydihPU195ZWFyc18yMDE5MDMyOSwgc3RhdHVzX291dF8yMDE5MDMyOSkgfiBHaW5pSW5kZXgsIGRhdGEgPSBmaWcyX05vQ2Vuc29yLmN1dC5jYXQpCgpnZ3N1cnZwbG90KGZpZzJfTm9DZW5zb3IuY3V0LmZpdCwKICAgICAgICAgICBkYXRhID0gZmlnMl9Ob0NlbnNvci5jdXQuY2F0LAogICAgICAgICAgIHJpc2sudGFibGUgPSBUUlVFLAogICAgICAgICAgIHB2YWwgPSBUKQpgYGAKCmBgYHtyfQpnZ3N1cnZwbG90KGZpZzJfTm9DZW5zb3IuY3V0LmZpdCwKICAgICAgICAgICAgcHZhbCA9IFRSVUUsCiAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjZTY0YjM1IiwgIiM0ZGJiZDUiKSwKICAgICAgICAgICAgYnJlYWsudGltZS5ieSA9IDIsCiAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9jbGFzc2ljKCksCiAgICAgICAgICAgIGxlZ2VuZC5sYWJzID0gYygiQWJvdmUgbWVkaWFuIiwgIlVuZGVyIG1lZGlhbiIpLAogICAgICAgICAgICByaXNrLnRhYmxlID0gImFic19wY3QiLAogICAgICAgICAgICByaXNrLnRhYmxlLnkudGV4dCA9IEZBTFNFLAogICAgICAgICAgICB4bGFiID0gIlRpbWUgKHllYXJzKSIsCiAgICAgICAgICAgIHRpdGxlID0gImdpbmlTdXJ2X3dpdGhvdXRfY2Vuc29yaW5nIiwKICAgICAgICAgICAgYXhlcy5vZmZzZXQgPSBGQUxTRSwKICAgICAgICAgICAgcmlzay50YWJsZS5mb250c2l6ZSA9IDIuNSwKICAgICAgICAgICAgbGVnZW5kID0gYygwLjksMC45KSwKICAgICAgICAgICAgcmlzay50YWJsZS50aXRsZSA9ICJOdW1iZXIgYXQgcmlzayBieSB0aW1lOiBuICglKSIsCiAgICAgICAgICAgIGZvbnQubWFpbiA9IGMoKSkKYGBgCgoKCgojIyMgQUMgcGF0aWVudAoKYGBge3J9CkdpbmlDbGluX3R1bW9yX0FjID0gR2luaUNsaW5fdHVtb3JbR2luaUNsaW5fdHVtb3IkaGlzdG9sb2d5X0hhbnNfQl9XSE9fMjAxNSA9PSAiQUMiLCBdCgpmaWcyQUN0ZXN0IDwtIHN1cnZmaXQoU3VydihPU195ZWFyc181X3llYXJzX3RydW5rXzIwMTkwMzI5LCBzdGF0dXNfNV95ZWFyc190cnVua18yMDE5MDMyOSkgfiBnaW5pR3JvdXAsIGRhdGEgPSBHaW5pQ2xpbl90dW1vcl9BYykKCnByaW50KGZpZzJBQ3Rlc3QpCnByaW50KCI9PT09IikKc3VtbWFyeShmaWcyQUN0ZXN0KSR0YWJsZQpgYGAKCmBgYHtyfQpmaWcyYV9BQyA8LSBnZ3N1cnZwbG90KGZpZzJBQ3Rlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgIHB2YWwgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gYygiI2U2NGIzNSIsICIjNGRiYmQ1IiksCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrLnRpbWUuYnkgPSAxLAogICAgICAgICAgICAgICAgICAgICAgICBnZ3RoZW1lID0gdGhlbWVfY2xhc3NpYygpLAogICAgICAgICAgICAgICAgICAgICAgICAjbGVnZW5kLmxhYnMgPSBjKCJBYm92ZSBtZWRpYW4iLCAiVW5kZXIgbWVkaWFuIiksCiAgICAgICAgICAgICAgICAgICAgICAgIHJpc2sudGFibGUgPSAiYWJzX3BjdCIsCiAgICAgICAgICAgICAgICAgICAgICAgIHJpc2sudGFibGUueS50ZXh0ID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiVGltZSAoeWVhcnMpIiwKICAgICAgICAgICAgICAgICAgICAgICAgeGxpbSA9IGMoMCw1LjIpLAogICAgICAgICAgICAgICAgICAgICAgICBheGVzLm9mZnNldCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICByaXNrLnRhYmxlLmZvbnRzaXplID0gMi41LAogICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQgPSBjKDAuOSwwLjkpLAogICAgICAgICAgICAgICAgICAgICAgICByaXNrLnRhYmxlLnRpdGxlID0gIk51bWJlciBhdCByaXNrIGJ5IHRpbWU6IG4gKCUpIiwKICAgICAgICAgICAgICAgICAgICAgICAgZm9udC5tYWluID0gYygpKQoKCmZpZzJhX0FDCmBgYAoKIyMjIyB3aXRob3V0IHNlbnNvcmluZwpgYGB7cn0KZmlnMkFDX05vQ2Vuc29yX3Rlc3QgPC0gc3VydmZpdChTdXJ2KE9TX3llYXJzXzIwMTkwMzI5LCBzdGF0dXNfb3V0XzIwMTkwMzI5KSB+IGdpbmlHcm91cCwgZGF0YSA9IEdpbmlDbGluX3R1bW9yW0dpbmlDbGluX3R1bW9yJGhpc3RvbG9neV9IYW5zX0JfV0hPXzIwMTUgPT0gIkFDIiwgXSkKCnByaW50KGZpZzJBQ19Ob0NlbnNvcl90ZXN0KQoKc3VtbWFyeShmaWcyQUNfTm9DZW5zb3JfdGVzdCkkdGFibGUKYGBgCgpgYGB7cn0KZ2dzdXJ2cGxvdChmaWcyQUNfTm9DZW5zb3JfdGVzdCwKICAgICAgICAgIHB2YWwgPSBUUlVFLAogICAgICAgICAgcGFsZXR0ZSA9IGMoIiNlNjRiMzUiLCAiIzRkYmJkNSIpLAogICAgICAgICAgYnJlYWsudGltZS5ieSA9IDEsCiAgICAgICAgICBnZ3RoZW1lID0gdGhlbWVfY2xhc3NpYygpLAogICAgICAgICAgbGVnZW5kLmxhYnMgPSBjKCJBYm92ZSBtZWRpYW4iLCAiVW5kZXIgbWVkaWFuIiksCiAgICAgICAgICByaXNrLnRhYmxlID0gImFic19wY3QiLAogICAgICAgICAgcmlzay50YWJsZS55LnRleHQgPSBGQUxTRSwKICAgICAgICAgIHhsYWIgPSAiVGltZSAoeWVhcnMpIiwKICAgICAgICAgIHRpdGxlID0gImdpbmlTdXJ2X3dpdGhvdXRfY2Vuc29yaW5nIiwKICAgICAgICAgIGF4ZXMub2Zmc2V0ID0gRkFMU0UsCiAgICAgICAgICByaXNrLnRhYmxlLmZvbnRzaXplID0gMi41LAogICAgICAgICAgbGVnZW5kID0gYygwLjksMC45KSwKICAgICAgICAgIHJpc2sudGFibGUudGl0bGUgPSAiTnVtYmVyIGF0IHJpc2sgYnkgdGltZTogbiAoJSkiLAogICAgICAgICAgZm9udC5tYWluID0gYygpKQpgYGAKCgojIyMgU3FDQyBwYXRpZW50CgpgYGB7cn0KR2luaUNsaW5fdHVtb3JfU3FDQyA9IEdpbmlDbGluX3R1bW9yW0dpbmlDbGluX3R1bW9yJGhpc3RvbG9neV9IYW5zX0JfV0hPXzIwMTUgPT0gIlNxQ0MiLCBdCgpmaWcyU3FDQ3Rlc3RfMiA8LSBzdXJ2Zml0KFN1cnYoT1NfeWVhcnNfNV95ZWFyc190cnVua18yMDE5MDMyOSwgc3RhdHVzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjkpIH4gZ2luaUdyb3VwLCBkYXRhID0gR2luaUNsaW5fdHVtb3JfU3FDQykKCnByaW50KGZpZzJTcUNDdGVzdCkKcHJpbnQoIj09PT0iKQpzdW1tYXJ5KGZpZzJTcUNDdGVzdCkkdGFibGUKYGBgCgpgYGB7cn0KZmlnMmFfU3FDQ18yIDwtIGdnc3VydnBsb3QoZmlnMlNxQ0N0ZXN0XzIsCiAgICAgICAgICAgICAgICAgICAgICAgIHB2YWwgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gYygiI2U2NGIzNSIsICIjNGRiYmQ1IiksCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrLnRpbWUuYnkgPSAxLAogICAgICAgICAgICAgICAgICAgICAgICBnZ3RoZW1lID0gdGhlbWVfY2xhc3NpYygpLAogICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQubGFicyA9IGMoIkFib3ZlIG1lZGlhbiIsICJVbmRlciBtZWRpYW4iKSwKICAgICAgICAgICAgICAgICAgICAgICAgcmlzay50YWJsZSA9ICJhYnNfcGN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgcmlzay50YWJsZS55LnRleHQgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgeGxhYiA9ICJUaW1lICh5ZWFycykiLAogICAgICAgICAgICAgICAgICAgICAgICB4bGltID0gYygwLDUuMiksCiAgICAgICAgICAgICAgICAgICAgICAgIGF4ZXMub2Zmc2V0ID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgIHJpc2sudGFibGUuZm9udHNpemUgPSAyLjUsCiAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZCA9IGMoMC45LDAuOSksCiAgICAgICAgICAgICAgICAgICAgICAgIHJpc2sudGFibGUudGl0bGUgPSAiTnVtYmVyIGF0IHJpc2sgYnkgdGltZTogbiAoJSkiLAogICAgICAgICAgICAgICAgICAgICAgICBmb250Lm1haW4gPSBjKCkpCgoKZmlnMmFfU3FDQ18yCmBgYAoKCgoKCmBgYHtyfQpmaWcyX1NxQ0NfdGltZXNwbCA8LSBzdXJ2U3BsaXQoU3VydihPU195ZWFyc181X3llYXJzX3RydW5rXzIwMTkwMzI5LCBzdGF0dXNfNV95ZWFyc190cnVua18yMDE5MDMyOSA9PSAxKSB+IC4sIGRhdGE9R2luaUNsaW5fdHVtb3JfU3FDQywgY3V0PTIsIGVwaXNvZGUgPSAidGdyb3VwIikKCmZpZzJfU3FDQ190aW1lc3BsLmNveCA8LSBjb3hwaChTdXJ2KHRzdGFydCwgT1NfeWVhcnNfNV95ZWFyc190cnVua18yMDE5MDMyOSwgZXZlbnQ9PTEpIH4gZ2luaUdyb3VwOnN0cmF0YSh0Z3JvdXApLCBkYXRhPWZpZzJfU3FDQ190aW1lc3BsLCB0aWVzPSJlZnJvbiIpCnN1bW1hcnkoZmlnMl9TcUNDX3RpbWVzcGwuY294KQpgYGAKCiMjIyMgd2l0aG91dCBzZW5zb3JpbmcKYGBge3J9CmZpZzJTcUNDX05vQ2Vuc29yX3Rlc3QgPC0gc3VydmZpdChTdXJ2KE9TX3llYXJzXzIwMTkwMzI5LCBzdGF0dXNfb3V0XzIwMTkwMzI5KSB+IGdpbmlHcm91cCwgZGF0YSA9IEdpbmlDbGluX3R1bW9yW0dpbmlDbGluX3R1bW9yJGhpc3RvbG9neV9IYW5zX0JfV0hPXzIwMTUgPT0gIlNxQ0MiLCBdKQoKcHJpbnQoZmlnMlNxQ0NfTm9DZW5zb3JfdGVzdCkKCnN1bW1hcnkoZmlnMlNxQ0NfTm9DZW5zb3JfdGVzdCkkdGFibGUKYGBgCgpgYGB7cn0KZ2dzdXJ2cGxvdChmaWcyU3FDQ19Ob0NlbnNvcl90ZXN0LAogICAgICAgICAgcHZhbCA9IFRSVUUsCiAgICAgICAgICBwYWxldHRlID0gYygiI2U2NGIzNSIsICIjNGRiYmQ1IiksCiAgICAgICAgICBicmVhay50aW1lLmJ5ID0gMSwKICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9jbGFzc2ljKCksCiAgICAgICAgICBsZWdlbmQubGFicyA9IGMoIkFib3ZlIG1lZGlhbiIsICJVbmRlciBtZWRpYW4iKSwKICAgICAgICAgIHJpc2sudGFibGUgPSAiYWJzX3BjdCIsCiAgICAgICAgICByaXNrLnRhYmxlLnkudGV4dCA9IEZBTFNFLAogICAgICAgICAgeGxhYiA9ICJUaW1lICh5ZWFycykiLAogICAgICAgICAgdGl0bGUgPSAiZ2luaVN1cnZfd2l0aG91dF9jZW5zb3JpbmciLAogICAgICAgICAgYXhlcy5vZmZzZXQgPSBGQUxTRSwKICAgICAgICAgIHJpc2sudGFibGUuZm9udHNpemUgPSAyLjUsCiAgICAgICAgICBsZWdlbmQgPSBjKDAuOSwwLjkpLAogICAgICAgICAgcmlzay50YWJsZS50aXRsZSA9ICJOdW1iZXIgYXQgcmlzayBieSB0aW1lOiBuICglKSIsCiAgICAgICAgICBmb250Lm1haW4gPSBjKCkpCmBgYAoKCiMjIyBUYWJsZTogQ294IHJlZ3Jlc3Npb24KClNpbmdsZSB2YXJpYXRlCmBgYHtyfQpHaW5pQ2xpbl90dW1vciRnaW5pR3JvdXAgPSBmYWN0b3IoR2luaUNsaW5fdHVtb3IkZ2luaUdyb3VwLCBsZXZlbHMgPSBjKCJVbmRlciBtZWRpYW4iLCAiQWJvdmUgbWVkaWFuIikpCgpmaWcyLmNveCA8LSBjb3hwaChTdXJ2KE9TX3llYXJzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjksIHN0YXR1c181X3llYXJzX3RydW5rXzIwMTkwMzI5KSB+IGdpbmlHcm91cCwgZGF0YSA9IEdpbmlDbGluX3R1bW9yKQoKcHJpbnQoIj09PSIpCmZpZzIuY294CnByaW50KCI9PT0iKQpwcmludChzdW1tYXJ5KGZpZzIuY294KSkKcHJpbnQoIj09PSIpCmBgYAoKCmBgYHtyfQpjb3guenBoKGZpZzIuY294KQpgYGAKCgpgYGB7cn0KIyBNZXJnZSB0aGUgaGlzdG9sb2d5IGdyb3VwIGV4Y2VwdCBBQyBhbmQgU3FDQyB0byBvdGhlcnMKR2luaUNsaW5fdHVtb3JbIShHaW5pQ2xpbl90dW1vciRoaXN0b2xvZ3lfSGFuc19CX1dIT18yMDE1ICVpbiUgYygiQUMiLCJTcUNDIikpLCAiSGlzdG9sb2d5Il0gPC0gIk90aGVyIgpHaW5pQ2xpbl90dW1vcltHaW5pQ2xpbl90dW1vciRoaXN0b2xvZ3lfSGFuc19CX1dIT18yMDE1ID09ICJBQyIsICJIaXN0b2xvZ3kiXSA8LSAiQUMiCkdpbmlDbGluX3R1bW9yW0dpbmlDbGluX3R1bW9yJGhpc3RvbG9neV9IYW5zX0JfV0hPXzIwMTUgPT0gIlNxQ0MiLCAiSGlzdG9sb2d5Il0gPC0gIlNxQ0MiCmBgYAoKYGBge3J9CiMgTWVyZ2UgdGhlIGN1cnJlbnQgc21va2UgYW5kIGZvcm1lciBzbW9rZSBpbiB0byBvbmUgZ3JvdXAKR2luaUNsaW5fdHVtb3JbR2luaUNsaW5fdHVtb3Ikc21va2UgJWluJSBjKCJDdXJyZW50IHNtb2tlIiwiRm9ybWVyIHNtb2tlIiksICJzbW9rZUdyb3VwIl0gPC0gIkN1cnJlbnQvRm9ybWVyIgpHaW5pQ2xpbl90dW1vcltHaW5pQ2xpbl90dW1vciRzbW9rZSA9PSAiTmV2ZXIgc21va2UiLCAic21va2VHcm91cCJdIDwtICJOZXZlciIKYGBgCgoKYGBge3J9CiMgQ29uc3RydWN0IGxldmVscyBvZiBlYWNoIHBhcmFtZXRlcgpHaW5pQ2xpbl90dW1vciRzdGFnZUdyb3VwID0gZmFjdG9yKEdpbmlDbGluX3R1bW9yJHN0YWdlR3JvdXAsIGxldmVscyA9IGMoIkxvdyBzdGFnZSIsICJIaWdoIHN0YWdlIikpCkdpbmlDbGluX3R1bW9yJGdlbmRlciA9IGZhY3RvcihHaW5pQ2xpbl90dW1vciRnZW5kZXIsIGxldmVscyA9IGMoIk1hbGUiLCAiRmVtYWxlIikpCkdpbmlDbGluX3R1bW9yJEhpc3RvbG9neSA9IGZhY3RvcihHaW5pQ2xpbl90dW1vciRIaXN0b2xvZ3ksIGxldmVscyA9IGMoIkFDIiwgIlNxQ0MiLCAiT3RoZXIiKSkKR2luaUNsaW5fdHVtb3IkYWdlR3JvdXAgPSBmYWN0b3IoR2luaUNsaW5fdHVtb3IkYWdlR3JvdXAsIGxldmVscyA9IGMoIlVuZGVyIDcwIiwgIkFib3ZlIDcwIikpCkdpbmlDbGluX3R1bW9yJHNtb2tlR3JvdXAgPSBmYWN0b3IoR2luaUNsaW5fdHVtb3Ikc21va2VHcm91cCwgbGV2ZWxzID0gYygiTmV2ZXIiLCJDdXJyZW50L0Zvcm1lciIpKQpgYGAKCiMjIyMgTXVsdGktdmFyaWF0ZSBjb3ggcmVncmVzc2lvbgoKYGBge3J9CmZpZzIubXVsdGljb3ggPC0gY294cGgoU3VydihPU195ZWFyc181X3llYXJzX3RydW5rXzIwMTkwMzI5LCBzdGF0dXNfNV95ZWFyc190cnVua18yMDE5MDMyOSkgfiBnaW5pR3JvdXAgKyBhZ2VHcm91cCArIGdlbmRlciArIHNtb2tlR3JvdXAgKyBIaXN0b2xvZ3kgKyBzdGFnZUdyb3VwLCBkYXRhID0gR2luaUNsaW5fdHVtb3IpCgpzdW1tYXJ5KGZpZzIubXVsdGljb3gpCmBgYAoKCiMjIyBXaXRob3V0IGFkanV2ZW50IHRyZWF0bWVudApgYGB7cn0KIyBTdWJzZXQgdGhlIGdyb3VwIHdpdGhvdXQgYWRqdXZlbnQgdHJlYXRtZW50CkdpbmlDbGluX25vVHJlYXQgPSBzdWJzZXQoR2luaUNsaW5fdHVtb3IsIEFubmV0dGVfYWRqdXZhbnQgPT0gMCkKCkdpbmlDbGluX25vVHJlYXQgPSBhcy5kYXRhLmZyYW1lKEdpbmlDbGluX25vVHJlYXQpCgpHaW5pQ2xpbl9ub1RyZWF0JGdpbmlHcm91cCA9IGZhY3RvcihHaW5pQ2xpbl9ub1RyZWF0JGdpbmlHcm91cCwgbGV2ZWxzID0gYygiQWJvdmUgbWVkaWFuIiwgIlVuZGVyIG1lZGlhbiIpKQoKIyBjb25zdHJ1Y3QgdGhlIG9iamVjdApmaWc4dGVzdCA8LSBzdXJ2Zml0KFN1cnYoT1NfeWVhcnNfNV95ZWFyc190cnVua18yMDE5MDMyOSwgc3RhdHVzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjkpIH4gZ2luaUdyb3VwLCBkYXRhID0gR2luaUNsaW5fbm9UcmVhdCkKCnByaW50KGZpZzh0ZXN0KQoKc3VtbWFyeShmaWc4dGVzdCkkdGFibGUKYGBgCgoKYGBge3J9CmZpZzhhX2FsbCA8LSBnZ3N1cnZwbG90KGZpZzh0ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICBwdmFsID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZSA9IGMoIiNlNjRiMzUiLCAiIzRkYmJkNSIpLAogICAgICAgICAgICAgICAgICAgICAgICBicmVhay50aW1lLmJ5ID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgZ2d0aGVtZSA9IHRoZW1lX2NsYXNzaWMoKSwKICAgICAgICAgICAgICAgICAgICAgICAgI2xlZ2VuZC5sYWJzID0gYygiQWJvdmUgbWVkaWFuIiwgIlVuZGVyIG1lZGlhbiIpLAogICAgICAgICAgICAgICAgICAgICAgICByaXNrLnRhYmxlID0gImFic19wY3QiLAogICAgICAgICAgICAgICAgICAgICAgICByaXNrLnRhYmxlLnkudGV4dCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICB4bGFiID0gIlRpbWUgKHllYXJzKSIsCiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlID0gImdpbmlTdXJ2X25vX3RyZWF0bWVudCIsCiAgICAgICAgICAgICAgICAgICAgICAgIHhsaW0gPSBjKDAsNS4yKSwKICAgICAgICAgICAgICAgICAgICAgICAgYXhlcy5vZmZzZXQgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgcmlzay50YWJsZS5mb250c2l6ZSA9IDIuNSwKICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kID0gYygwLjksMC45KSwKICAgICAgICAgICAgICAgICAgICAgICAgcmlzay50YWJsZS50aXRsZSA9ICJOdW1iZXIgYXQgcmlzayBieSB0aW1lOiBuICglKSIsCiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnQubWFpbiA9IGMoKSkKCgpmaWc4YV9hbGwKYGBgCgpgYGB7cn0KIyBTdWJzZXQgdGhlIGdyb3VwIHdpdGggYWRqdXZlbnQgdHJlYXRtZW50CkdpbmlDbGluX1RyZWF0ID0gc3Vic2V0KEdpbmlDbGluX3R1bW9yLCBBbm5ldHRlX2FkanV2YW50ID09IDEpCgpHaW5pQ2xpbl9UcmVhdCA9IGFzLmRhdGEuZnJhbWUoR2luaUNsaW5fVHJlYXQpCgpHaW5pQ2xpbl9UcmVhdCRnaW5pR3JvdXAgPSBmYWN0b3IoR2luaUNsaW5fVHJlYXQkZ2luaUdyb3VwLCBsZXZlbHMgPSBjKCJBYm92ZSBtZWRpYW4iLCAiVW5kZXIgbWVkaWFuIikpCgojIGNvbnN0cnVjdCB0aGUgb2JqZWN0CmZpZzh0ZXN0XzIgPC0gc3VydmZpdChTdXJ2KE9TX3llYXJzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjksIHN0YXR1c181X3llYXJzX3RydW5rXzIwMTkwMzI5KSB+IGdpbmlHcm91cCwgZGF0YSA9IEdpbmlDbGluX1RyZWF0KQoKcHJpbnQoZmlnOHRlc3RfMikKCnN1bW1hcnkoZmlnOHRlc3RfMikkdGFibGUKYGBgCgoKYGBge3J9CmZpZzhiX2FsbF8yIDwtIGdnc3VydnBsb3QoZmlnOHRlc3RfMiwKICAgICAgICAgICAgICAgICAgICAgICAgcHZhbCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjZTY0YjM1IiwgIiM0ZGJiZDUiKSwKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsudGltZS5ieSA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9jbGFzc2ljKCksCiAgICAgICAgICAgICAgICAgICAgICAgICNsZWdlbmQubGFicyA9IGMoIkFib3ZlIG1lZGlhbiIsICJVbmRlciBtZWRpYW4iKSwKICAgICAgICAgICAgICAgICAgICAgICAgcmlzay50YWJsZSA9ICJhYnNfcGN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgcmlzay50YWJsZS55LnRleHQgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgeGxhYiA9ICJUaW1lICh5ZWFycykiLAogICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJnaW5pU3Vydl90cmVhdG1lbnQiLAogICAgICAgICAgICAgICAgICAgICAgICB4bGltID0gYygwLDUuMiksCiAgICAgICAgICAgICAgICAgICAgICAgIGF4ZXMub2Zmc2V0ID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgIHJpc2sudGFibGUuZm9udHNpemUgPSAyLjUsCiAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZCA9IGMoMC45LDAuOSksCiAgICAgICAgICAgICAgICAgICAgICAgIHJpc2sudGFibGUudGl0bGUgPSAiTnVtYmVyIGF0IHJpc2sgYnkgdGltZTogbiAoJSkiLAogICAgICAgICAgICAgICAgICAgICAgICBmb250Lm1haW4gPSBjKCkpCgoKZmlnOGJfYWxsXzIKYGBgCiMgRmlndXJlIG11dGF0aW9uIGJ1cmRlbgoKIyMgTXV0YXRpb24gYnVyZGVuCgpgYGB7cn0KbXV0Q2xpbiA8LSByZWFkX2V4Y2VsKCJ+L1Byb2plY3QvVENSX1N1bW1hcnkvV3JpdGluZy9TdW1TdXAueGxzeCIsIHNoZWV0ID0gIk11dGF0aW9uQnVyZGVybl9hbGxfdHVtb3IiKQoKbXV0Q2xpbiA8LSBhcy5kYXRhLmZyYW1lKG11dENsaW4sIHJvdy5uYW1lcyA9IG11dENsaW4kSUQpCgptdXRDbGluJEFCX0dpbmlJbmRleCA8LSBhcy5udW1lcmljKG11dENsaW4kQUJfR2luaUluZGV4KQptdXRDbGluJE11dGF0aW9uX2xvYWRfYWxsbXV0YXRpb25zIDwtIGFzLm51bWVyaWMobXV0Q2xpbiRNdXRhdGlvbl9sb2FkX2FsbG11dGF0aW9ucykKbXV0Q2xpbiA8LSBtdXRDbGluW2ludGVyc2VjdChyb3duYW1lcyhtdXRDbGluKSwgcm93bmFtZXMoR2luaUNsaW5fdHVtb3IpKSxdCmBgYAoKYGBge3J9CmZpZzRhIDwtIGdnc2NhdHRlcihtdXRDbGluWyxjKCJBQl9HaW5pSW5kZXgiLCJNdXRhdGlvbl9sb2FkX2FsbG11dGF0aW9ucyIpXSwgeCA9ICJBQl9HaW5pSW5kZXgiLCB5ID0gIk11dGF0aW9uX2xvYWRfYWxsbXV0YXRpb25zIiwKICAgICAgICAgICAgICAgICAgIGFkZD0icmVnLmxpbmUiLCBhZGQucGFyYW1zID0gbGlzdChjb2xvciA9ICIjMDBiZmM0IiksCiAgICAgICAgICAgICAgICAgICBjb25mLmludCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgY29yLmNvZWYgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgY29yLmNvZWZmLmFyZ3MgPSBsaXN0KG1ldGhvZCA9ICJzcGVhcm1hbiIsIGxhYmVsLngubnBjID0gMC4xNSwgbGFiZWwueS5ucGMgPSAwLjg1KSwKICAgICAgICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9jbGFzc2ljKCksCiAgICAgICAgICAgICAgICAgICAjYWRkID0gInJlZy5saW5lIiwgYWRkLnBhcmFtcyA9IGMoY29sb3IgPSAnIzAwYmZjNCcpLAogICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiTXV0YXRpb24gYnVyZGVuIiwgeGxhYiA9ICJHaW5pIEluZGV4IiwgeWxhYiA9ICJNdXRhdGlvbiBsb2FkIG9mIGFsbCBtdXRhdGlvbnMiLAogICAgICAgICAgICAgICAgICAgZm9udC50aWNrc2xhYiA9IGMoc2l6ZT0xNSwgY29sb3IgPSAiYmxhY2siKSwgZm9udC5tYWluID0gMjAsZm9udC55ID0gMTUsIGZvbnQueCA9IDE1KSArCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSwgbGltaXRzID0gYygwLCAxMzApLCBicmVha3MgPSBjKHNlcSgwLDEyMCwzMCkpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSwgbGltaXRzID0gYygwLCAwLjc1KSwgYnJlYWtzID0gYyhzZXEoMCwwLjYsMC4yKSkpCgpmaWc0YQpgYGAKCiMjIE11dGF0aW9uCgpgYGB7cn0KbXV0R2luaSA8LSByZWFkX2V4Y2VsKCJ+L1Byb2plY3QvVENSX1N1bW1hcnkvV3JpdGluZy9TdW1TdXAueGxzeCIsIHNoZWV0ID0gIm11dGF0aW9uX3R1bW9yIikKCm11dEdpbmkgPC0gYXMuZGF0YS5mcmFtZShtdXRHaW5pLCByb3cubmFtZXMgPSBtdXRHaW5pJElEKQptdXRHaW5pJElEIDwtIE5VTEwKCm11dEdpbmkgPC0gbXV0R2luaVtpbnRlcnNlY3Qocm93bmFtZXMobXV0R2luaSksIHJvd25hbWVzKEdpbmlDbGluX3R1bW9yKSksXQptdXRHaW5pJENDTkQxIDwtIE5VTEwKCm11dFRlc3QgPC0gbGlzdCgpCmZvciAobXV0R2VuZSBpbiBjb2xuYW1lcyhtdXRHaW5pWywoMzo4MyldKSl7CiAgV1RfYnVmZiA8LSBtdXRHaW5pW211dEdpbmlbLG11dEdlbmVdID09ICJXVCIsIkdpbmlJbmRleCJdCiAgTXV0X2J1ZmYgPC0gbXV0R2luaVttdXRHaW5pWyxtdXRHZW5lXSA9PSAiTXV0YXRlZCIsIkdpbmlJbmRleCJdCiAgbXV0UmVzIDwtIHdpbGNveC50ZXN0KFdUX2J1ZmYsTXV0X2J1ZmYpCiAgbXV0VGVzdCA8LSBjKG11dFRlc3QsYyhtdXRHZW5lLG11dFJlcyRzdGF0aXN0aWMsbXV0UmVzJHAudmFsdWUpKQp9CgptdXRUZXN0Lm1hdHJpeCA8LSBtYXRyaXgobXV0VGVzdCwgbmNvbCA9IDMsIGJ5cm93ID0gVFJVRSkKY29sbmFtZXMobXV0VGVzdC5tYXRyaXgpIDwtIGMoIk11dGF0aW9uIiwgIndpbC5jb3giLCAicF92YWx1ZSIpCm11dFRlc3QubWF0cml4IDwtIGFzLmRhdGEuZnJhbWUobXV0VGVzdC5tYXRyaXgpCm11dFRlc3QubWF0cml4WywiRkRSIl0gPC0gcC5hZGp1c3QobXV0VGVzdC5tYXRyaXgkcF92YWx1ZSwgbWV0aG9kID0gImZkciIpCgpgYGAKCiMjIyBFR0ZSCmBgYHtyfQpmNGMuZWdmciA8LSBnZ3Bsb3QobXV0R2luaSwgYWVzKHggPSBFR0ZSLCB5ID0gR2luaUluZGV4LCBmaWxsID0gRUdGUikpICsKICBnZW9tX2JveHBsb3Qob3V0bGllci5jb2xvdXIgPSAiYmxhY2siLCBvdXRsaWVyLnNoYXBlID0gMTYsIG91dGxpZXIuc2l6ZSA9IDIsY29sb3IgPSJibGFjayIpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogICMgY29vcmRfZmxpcCgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjRkZFNUQ0IiwgIiNFNkVCRTAiKSkgKwogIGxhYnModGl0bGUgPSAiRUdGUiIsIHggPSBOVUxMKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSkKZjRjLmVnZnIKYGBgCgojIyMgQVBDCmBgYHtyfQpmNGMuYXBjIDwtIGdncGxvdChtdXRHaW5pLCBhZXMoeCA9IEFQQywgeSA9IEdpbmlJbmRleCwgZmlsbD1BUEMpKSArCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3VyID0gImJsYWNrIiwgb3V0bGllci5zaGFwZSA9IDE2LCBvdXRsaWVyLnNpemUgPSAyLCBjb2xvdXIgPSAiYmxhY2siKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICAjIGNvb3JkX2ZsaXAoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0ZGRTVENCIsICIjRTZFQkUwIikpICsKICBsYWJzKHRpdGxlID0gIkFQQyIsIHggPSBOVUxMKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSkKZjRjLmFwYwpgYGAKCiMjIyBUUDUzCmBgYHtyfQpmNGMudHA1MyA8LSBnZ3Bsb3QobXV0R2luaSwgYWVzKHggPSBUUDUzLCB5ID0gR2luaUluZGV4LCBmaWxsPVRQNTMpKSArCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3VyID0gImJsYWNrIiwgb3V0bGllci5zaGFwZSA9IDE2LCBvdXRsaWVyLnNpemUgPSAyLCBjb2xvdXIgPSAiYmxhY2siKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICAjIGNvb3JkX2ZsaXAoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0ZGRTVENCIsICIjRTZFQkUwIikpICsKICBsYWJzKHRpdGxlID0gIlRQNTMiLCB4ID0gTlVMTCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gRkFMU0UpCmY0Yy50cDUzCmBgYAojIyMgQVJJRDFBCmBgYHtyfQpmNGMuYXJpZDFhIDwtIGdncGxvdChtdXRHaW5pLCBhZXMoeCA9IEFSSUQxQSwgeSA9IEdpbmlJbmRleCwgZmlsbD1BUklEMUEpKSArCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3VyID0gImJsYWNrIiwgb3V0bGllci5zaGFwZSA9IDE2LCBvdXRsaWVyLnNpemUgPSAyLCBjb2xvdXIgPSAiYmxhY2siKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICAjIGNvb3JkX2ZsaXAoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0ZGRTVENCIsICIjRTZFQkUwIikpICsKICBsYWJzKHRpdGxlID0gIkFSSUQxQSIsIHggPSBOVUxMKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSkKZjRjLmFyaWQxYQpgYGAKCiMjIyBFUEhCNgpgYGB7cn0KZjRjLmVwaGI2IDwtIGdncGxvdChtdXRHaW5pLCBhZXMoeCA9IEVQSEI2LCB5ID0gR2luaUluZGV4LCBmaWxsPUVQSEI2KSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLmNvbG91ciA9ICJibGFjayIsIG91dGxpZXIuc2hhcGUgPSAxNiwgb3V0bGllci5zaXplID0gMiwgY29sb3VyID0gImJsYWNrIikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgIyBjb29yZF9mbGlwKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNGRkU1RDQiLCAiI0U2RUJFMCIpKSArCiAgbGFicyh0aXRsZSA9ICJFUEhCNiIsIHggPSBOVUxMKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBGQUxTRSkKZjRjLmVwaGI2CmBgYAoKIyMjIENTTUQzCmBgYHtyfQpmNGMuY3NtZDMgPC0gZ2dwbG90KG11dEdpbmksIGFlcyh4ID0gQ1NNRDMsIHkgPSBHaW5pSW5kZXgsIGZpbGw9Q1NNRDMpKSArCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3VyID0gImJsYWNrIiwgb3V0bGllci5zaGFwZSA9IDE2LCBvdXRsaWVyLnNpemUgPSAyLCBjb2xvdXIgPSAiYmxhY2siKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICAjIGNvb3JkX2ZsaXAoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0ZGRTVENCIsICIjRTZFQkUwIikpICsKICBsYWJzKHRpdGxlID0gIkNTTUQzIiwgeCA9IE5VTEwpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIiksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MjAsIGhqdXN0ID0gMC41KSkgKwogICMsIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxLCBmaWxsID0gTkEpCiAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IEZBTFNFKQpmNGMuY3NtZDMKYGBgCgojIyMgQ29tYmluZQpgYGB7cn0KZ2dhcnJhbmdlKGY0Yy5lZ2ZyLCBmNGMuYXBjLCBmNGMudHA1MywgZjRjLmFyaWQxYSwgZjRjLmVwaGI2LCBmNGMuY3NtZDMsIG5jb2wgPSAyLCBucm93ID0gMywgYWxpZ24gPSAiaHYiKQpgYGAKCgoKIyBGaWd1cmUgSUhDIEhlYXRtYXAKCiMjIHByZXBhcmUgdGFibGUKYGBge3J9Cm11dF90X2Fubm8gPC0gcmVhZF9leGNlbCgifi9Qcm9qZWN0L1RDUl9TdW1tYXJ5L1dyaXRpbmcvU3VtU3VwLnhsc3giLCBzaGVldCA9ICJtdXRhdGlvbl90dW1vcl9hbm5vIikKCm11dF90X2Fubm8gPC0gYXMuZGF0YS5mcmFtZShtdXRfdF9hbm5vLCByb3cubmFtZXMgPSBtdXRfdF9hbm5vJElEKQoKbXV0X3RfYW5ubyRJRCA8LSBOVUxMCgppaGNBbm5vIDwtIG1lcmdlKEFCX0dpbmlfYW5ubywgbXV0X3RfYW5ubywgYnkgPSAicm93Lm5hbWVzIiwgYWxsID1UUlVFKQppaGNBbm5vIDwtIGFzLmRhdGEuZnJhbWUoaWhjQW5ubywgcm93Lm5hbWVzID0gaWhjQW5ubyRSb3cubmFtZXMpCmloY0Fubm8kUm93Lm5hbWVzIDwtIE5VTEwKaWhjQW5ubyA8LSBtZXJnZShpaGNBbm5vLCBtdXRHaW5pWyxjKCJBUEMiLCJBUklEMUEiLCJFUEhCNiIpXSxieSA9ICJyb3cubmFtZXMiLCBhbGw9RkFMU0UpCgppaGNBbm5vIDwtIG1lcmdlKGloY0Fubm8sIEdpbmlDbGluWyxjKCJoaXN0b2xvZ3lfSGFuc19CX1dIT18yMDE1IiwgImdlbmRlciIsICJzbW9rZSIsICJzdGF0dXNfNV95ZWFyc190cnVua18yMDE5MDMyOSIpXSwgYnkgPSAicm93Lm5hbWVzIixhbGwgPVRSVUUpCgppaGNBbm5vIDwtIHJlbmFtZShpaGNBbm5vLCBjKCJoaXN0b2xvZ3lfSGFuc19CX1dIT18yMDE1Ij0iaGlzdG9sb2d5IiwgInN0YXR1c181X3llYXJzX3RydW5rXzIwMTkwMzI5Ij0ic3VydjV5ZWFycyIpKQoKaWhjQW5ubyA8LSBhcy5kYXRhLmZyYW1lKGloY0Fubm8sIHJvdy5uYW1lcyA9IGloY0Fubm8kUm93Lm5hbWVzKQppaGNBbm5vJFJvdy5uYW1lcyA8LSBOVUxMCgppaGNBbm5vIDwtIGloY0Fubm9bLGMoMToyMCwgMjU6MjcsIDIxOjI0KV0KCmloY0hlYXRUX3R1bW9yX25vcm0gPC0gYXMuZGF0YS5mcmFtZShpaGNIZWF0VF90dW1vcl9ub3JtLCByb3cubmFtZXMgPSBpaGNIZWF0VF90dW1vcl9ub3JtJElEKQppaGNIZWF0VF90dW1vcl9ub3JtJElEIDwtIE5VTEwKaWhjSGVhdFRfdHVtb3Jfbm9ybSA8LSBhcy5kYXRhLmZyYW1lKGloY0hlYXRUX3R1bW9yX25vcm0pCgppaGNIZWF0VF90dW1vcl9ub3JtIDwtIHJlbmFtZShpaGNIZWF0VF90dW1vcl9ub3JtLCBjKCJHaW5pIEluZGV4IiA9ICJHaW5pLkluZGV4IikpCgppaGNBbm5vWyFpcy5uYShpaGNBbm5vJHNtb2tlKSAmIGloY0Fubm8kc21va2UgPT0gIk4iLCAic21va2UiXSA8LSAiTmV2ZXIiCmloY0Fubm9bIWlzLm5hKGloY0Fubm8kc21va2UpICYgaWhjQW5ubyRzbW9rZSA9PSAiRiIsICJzbW9rZSJdIDwtICJGb3JtZXIiCmloY0Fubm9bIWlzLm5hKGloY0Fubm8kc21va2UpICYgaWhjQW5ubyRzbW9rZSA9PSAiQyIsICJzbW9rZSJdIDwtICJDdXJyZW50IgoKaWhjQW5ub1shaXMubmEoaWhjQW5ubyRnZW5kZXIpICYgaWhjQW5ubyRnZW5kZXIgPT0gIkYiLCAiZ2VuZGVyIl0gPC0gIkZlbWFsZSIKaWhjQW5ub1shaXMubmEoaWhjQW5ubyRnZW5kZXIpICYgaWhjQW5ubyRnZW5kZXIgPT0gIk0iLCAiZ2VuZGVyIl0gPC0gIk1hbGUiCgppaGNBbm5vWyFpcy5uYShpaGNBbm5vJHN1cnY1eWVhcnMpICYgaWhjQW5ubyRzdXJ2NXllYXJzID09IDEsICJzdXJ2NXllYXJzIl0gPC0gIkRlYWQiCmloY0Fubm9bIWlzLm5hKGloY0Fubm8kc3VydjV5ZWFycykgJiBpaGNBbm5vJHN1cnY1eWVhcnMgPT0gMCwgInN1cnY1eWVhcnMiXSA8LSAiQWxpdmUiCgppaGNIZWF0VF90dW1vcl9ub3JtMiA8LSBpaGNIZWF0VF90dW1vcl9ub3JtWyFyb3duYW1lcyhpaGNIZWF0VF90dW1vcl9ub3JtKSAlaW4lIGMoIkw0ODNUIiwgIkw3MzFUIiksIF0KCmloY0hlYXRUX3R1bW9yX25vcm0zIDwtIGloY0hlYXRUX3R1bW9yX25vcm0yWyxncmVwKCJDRDQ0IiwgY29sbmFtZXMoaWhjSGVhdFRfdHVtb3Jfbm9ybTIpLCBpbnZlcnQgPSBUUlVFKV0KCmBgYAoKYGBge3J9CmloY0Fubm9fY29sb3IgPSBsaXN0KAogICJHaW5pIGluZGV4IiA9IGNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbChuID0gOSwgbmFtZSA9ICJSZWRzIikpKDEwMCksCiAgIktSQVMiID0gYyhNdXRhdGVkID0gIiNENDVGNTEiLCBXVCA9ICIjQjdEMkU4IiksCiAgIkVHRlIiID0gYyhNdXRhdGVkID0gIiNENDVGNTEiLCBXVCA9ICIjQjdEMkU4IiksCiAgIlBJSzNDQSIgPSBjKE11dGF0ZWQgPSAiI0Q0NUY1MSIsIFdUID0gIiNCN0QyRTgiKSwKICAiRkdGUjIiPSBjKE11dGF0ZWQgPSAiI0Q0NUY1MSIsIFdUID0gIiNCN0QyRTgiKSwKICAiUERHRlJBIj0gYyhNdXRhdGVkID0gIiNENDVGNTEiLCBXVCA9ICIjQjdEMkU4IiksCiAgIlJPUzEiPSBjKE11dGF0ZWQgPSAiI0Q0NUY1MSIsIFdUID0gIiNCN0QyRTgiKSwKICAiTkYxIiA9IGMoTXV0YXRlZCA9ICIjRDQ1RjUxIiwgV1QgPSAiI0I3RDJFOCIpLAogICJTVEsxMSIgPSBjKE11dGF0ZWQgPSAiI0Q0NUY1MSIsIFdUID0gIiNCN0QyRTgiKSwKICAiVFA1MyIgPSBjKE11dGF0ZWQgPSAiI0Q0NUY1MSIsIFdUID0gIiNCN0QyRTgiKSwKICAiS0VBUDEiID0gYyhNdXRhdGVkID0gIiNENDVGNTEiLCBXVCA9ICIjQjdEMkU4IiksCiAgIk5GRTJMMiIgPSBjKE11dGF0ZWQgPSAiI0Q0NUY1MSIsIFdUID0gIiNCN0QyRTgiKSwKICAiTVVDMTYiID0gYyhNdXRhdGVkID0gIiNENDVGNTEiLCBXVCA9ICIjQjdEMkU4IiksCiAgIktNVDJDIiA9IGMoTXV0YXRlZCA9ICIjRDQ1RjUxIiwgV1QgPSAiI0I3RDJFOCIpLAogICJLTVQyRCIgPSBjKE11dGF0ZWQgPSAiI0Q0NUY1MSIsIFdUID0gIiNCN0QyRTgiKSwKICAiU01BUkNBNCIgPSBjKE11dGF0ZWQgPSAiI0Q0NUY1MSIsIFdUID0gIiNCN0QyRTgiKSwKICAiQ0RLTjJBIiA9IGMoTXV0YXRlZCA9ICIjRDQ1RjUxIiwgV1QgPSAiI0I3RDJFOCIpLAogICJDUkVCQlAiID0gYyhNdXRhdGVkID0gIiNENDVGNTEiLCBXVCA9ICIjQjdEMkU4IiksCiAgIkNTTUQzIiA9IGMoTXV0YXRlZCA9ICIjRDQ1RjUxIiwgV1QgPSAiI0I3RDJFOCIpLAogICJMUlAxQiIgPSBjKE11dGF0ZWQgPSAiI0Q0NUY1MSIsIFdUID0gIiNCN0QyRTgiKSwKICAiQVBDIiA9IGMoTXV0YXRlZCA9ICIjRDQ1RjUxIiwgV1QgPSAiI0I3RDJFOCIpLAogICJBUklEMUEiID0gYyhNdXRhdGVkID0gIiNENDVGNTEiLCBXVCA9ICIjQjdEMkU4IiksCiAgIkVQSEI2IiA9IGMoTXV0YXRlZCA9ICIjRDQ1RjUxIiwgV1QgPSAiI0I3RDJFOCIpLAogICJoaXN0b2xvZ3kiID0gYyhBQyA9ICIjRDU1NzQwIiwgU3FDQyA9ICIjNERCQ0Q2IiwgQWRTcSA9ICIjNDc5RTg4IiwgTENDID0gIiM0MTUzODQiLCBMQ05FQyA9ICIjRjQ5QjdGIiwgU0MgPSAiI0Y4QkVENiIpLAogICJnZW5kZXIiID0gYyhNYWxlID0gIiNCOUUzREYiLCBGZW1hbGUgPSAiI0VGQzBENSIpLAogICJzbW9rZSIgPSBjKEN1cnJlbnQgPSAiI0Q0NUY1MSIsIEZvcm1lciA9ICIjRTY4ODQwIiwgTmV2ZXIgPSAiI0JDRDlCMiIpLAogICJzdXJ2NXllYXJzIiA9IGMoRGVhZCA9ICIjRDQ1RjUxIiwgQWxpdmUgPSAiI0I3RDJFOCIpCikKYGBgCgpgYGB7cn0KZmlnNWIgPC0gcGhlYXRtYXAodChpaGNIZWF0VF90dW1vcl9ub3JtMiksIGNsdXN0ZXJpbmdfbWV0aG9kID0gIndhcmQuRDIiLAogICAgICAgICAgICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX3Jvd3MgPSAiZXVjbGlkZWFuIiwgY2x1c3RlcmluZ19kaXN0YW5jZV9jb2xzID0gImV1Y2xpZGVhbiIsCiAgICAgICAgICAgICAgICAgIGN1dHJlZV9jb2xzID0gMywKICAgICAgICAgICAgICAgICAgI2NvbG9yID0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKG4gPSA3LCBuYW1lID0gIllsR25CdSIpKSgxMDApLAogICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uX2NvbCA9IGloY0Fubm8sCiAgICAgICAgICAgICAgICAgIGFubm90YXRpb25fY29sb3JzID0gaWhjQW5ub19jb2xvciwKICAgICAgICAgICAgICAgICAgZm9udHNpemUgPSA1LAogICAgICAgICAgICAgICAgICBzaG93X2NvbG5hbWVzID0gRgogICAgICAgICAgICAgICAgICApCmZpZzViCmBgYAoKYGBge3J9CmZpZzViLmNsdXN0ZXIgPC0gZmlnNWIkdHJlZV9jb2wKCmZpZzViLmNsdXN0ZXIucGxvdCA8LSBwbG90KGZpZzViLmNsdXN0ZXIsIGhhbmcgPSAtMSwgY2V4PTAuNiwgYXhlcz1GQUxTRSwgYW5uPUZBTFNFKQoKZmlnNWIuY3V0IDwtIGN1dHJlZShmaWc1Yi5jbHVzdGVyLCAzKQoKZmlnNWIuY3V0XzEgPC0gbmFtZXMoZmlnNWIuY3V0KVtmaWc1Yi5jdXQgPT0gMV0KZmlnNWIuY3V0XzIgPC0gbmFtZXMoZmlnNWIuY3V0KVtmaWc1Yi5jdXQgPT0gMl0KZmlnNWIuY3V0XzMgPC0gbmFtZXMoZmlnNWIuY3V0KVtmaWc1Yi5jdXQgPT0gM10KCmZpZzViLmN1dF9naW5pIDwtIG1lcmdlKEFCX0dpbmlfYW5ubywgZmlnNWIuY3V0LCBieSA9ICJyb3cubmFtZXMiLCBhbGwueSA9IFRSVUUpCgpmaWc1Yi5jdXRfZ2luaSA8LSBhcy5kYXRhLmZyYW1lKGZpZzViLmN1dF9naW5pLCByb3cubmFtZXMgPSBmaWc1Yi5jdXRfZ2luaSRSb3cubmFtZXMpCgpmaWc1Yi5jdXRfZ2luaSRSb3cubmFtZXMgPC0gTlVMTAoKZmlnNWIuY3V0X2dpbmkgPC0gcmVuYW1lKGZpZzViLmN1dF9naW5pLCBjKCJ5Ij0iQ2x1c3RlciIpKQpgYGAKCmBgYHtyfQpmaWc1Yi5jdXRfZ2luaVtmaWc1Yi5jdXRfZ2luaSRDbHVzdGVyID09IDIsICJDbGFzcyJdIDwtICJJbW11bmUgaG90IgpmaWc1Yi5jdXRfZ2luaVtmaWc1Yi5jdXRfZ2luaSRDbHVzdGVyID09IDMsICJDbGFzcyJdIDwtICJNZWRpYW4iCmZpZzViLmN1dF9naW5pW2ZpZzViLmN1dF9naW5pJENsdXN0ZXIgPT0gMSwgIkNsYXNzIl0gPC0gIkltbXVuZSBjb2xkIgpmaWc1Yi5jdXRfZ2luaSRDbGFzcyA9IGZhY3RvcihmaWc1Yi5jdXRfZ2luaSRDbGFzcywgbGV2ZWxzID0gYygiSW1tdW5lIGhvdCIsICJNZWRpYW4iLCAiSW1tdW5lIGNvbGQiKSkKYGBgCgoKYGBge3J9CmZpZzViLmN1dF9naW5pIDwtIGFzLmRhdGEuZnJhbWUoZmlnNWIuY3V0X2dpbmkpCmZpZzViLmN1dF9naW5pMiA8LSByZW5hbWUoZmlnNWIuY3V0X2dpbmksIGMoIkdpbmkgaW5kZXgiPSJHaW5pSW5kZXgiKSkKY29tcGFyZV9tZWFucyhHaW5pSW5kZXggfiBDbGFzcywgZGF0YSA9IGZpZzViLmN1dF9naW5pMikKYGBgCgoKYGBge3J9CmZpZzViLmN1dF9rbSA8LSBtZXJnZShmaWc1Yi5jdXRfZ2luaSwgR2luaUNsaW5fdHVtb3JbLCBjKCJPU195ZWFyc181X3llYXJzX3RydW5rXzIwMTkwMzI5IiwgInN0YXR1c181X3llYXJzX3RydW5rXzIwMTkwMzI5IildLCBieSA9ICJyb3cubmFtZXMiKQpmaWc1Yi5jdXRfa20gPC0gYXMuZGF0YS5mcmFtZShmaWc1Yi5jdXRfa20sIHJvdy5uYW1lcyA9IGZpZzViLmN1dF9rbSRSb3cubmFtZXMpCmZpZzViLmN1dF9rbSRSb3cubmFtZXMgPC0gTlVMTAoKZmlnNWIudGVzdCA8LSBzdXJ2Zml0KFN1cnYoT1NfeWVhcnNfNV95ZWFyc190cnVua18yMDE5MDMyOSwgc3RhdHVzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjkpIH4gQ2xhc3MsIGRhdGEgPSBmaWc1Yi5jdXRfa20pCgpzdW1tYXJ5KGZpZzViLnRlc3QpJHRhYmxlCmBgYAoKYGBge3J9CmZpZzViLktNIDwtIGdnc3VydnBsb3QoZmlnNWIudGVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgcHZhbCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjZTY0YjM1IiwgIiM0ZGJiZDUiLCAiIzk5OTk5OSIpLAogICAgICAgICAgICAgICAgICAgICAgICBicmVhay50aW1lLmJ5ID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgZ2d0aGVtZSA9IHRoZW1lX2NsYXNzaWMoKSwKICAgICAgICAgICAgICAgICAgICAgICAgI2xlZ2VuZC5sYWJzID0gYygiQWJvdmUgbWVkaWFuIiwgIlVuZGVyIG1lZGlhbiIpLAogICAgICAgICAgICAgICAgICAgICAgICByaXNrLnRhYmxlID0gImFic19wY3QiLAogICAgICAgICAgICAgICAgICAgICAgICByaXNrLnRhYmxlLnkudGV4dCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICB4bGFiID0gIlRpbWUgKHllYXJzKSIsCiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlID0gImdpbmlTdXJ2X0NsYXNzIiwKICAgICAgICAgICAgICAgICAgICAgICAgeGxpbSA9IGMoMCw1LjIpLAogICAgICAgICAgICAgICAgICAgICAgICBheGVzLm9mZnNldCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICByaXNrLnRhYmxlLmZvbnRzaXplID0gMi41LAogICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQgPSBjKDAuOSwwLjkpLAogICAgICAgICAgICAgICAgICAgICAgICByaXNrLnRhYmxlLnRpdGxlID0gIk51bWJlciBhdCByaXNrIGJ5IHRpbWU6IG4gKCUpIiwKICAgICAgICAgICAgICAgICAgICAgICAgZm9udC5tYWluID0gYygpKQpmaWc1Yi5LTQpgYGAKCmBgYHtyfQpmaWc1YyA8LSBnZ3Bsb3QoZmlnNWIuY3V0X2dpbmksIGFlcyh4ID0gQ2xhc3MsIHkgPSBgR2luaSBpbmRleGAsIGZpbGw9Q2xhc3MpKSArCiAgICBnZW9tX2JveHBsb3Qob3V0bGllci5jb2xvdXIgPSAiYmxhY2siLCBvdXRsaWVyLnNoYXBlID0gMTYsIG91dGxpZXIuc2l6ZSA9IDIsIGNvbG91ciA9ICJibGFjayIpICsKICAgIHRoZW1lX2NsYXNzaWMoKSArCiAgICAjIGNvb3JkX2ZsaXAoKSArCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjZTY0YjM1IiwgIiM0ZGJiZDUiLCAiIzk5OTk5OSIpKSArCiAgICBsYWJzKHRpdGxlID0gIkNsYXNzIiwgeCA9ICJDbGFzcyIpICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpICsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBOVUxMKQpmaWc1YwpgYGAKCgpgYGB7cn0KZmlnNWIuY3V0X2NsaW4gPC0gbWVyZ2UoZmlnNWIuY3V0X2ttLCBHaW5pQ2xpbl90dW1vclssYygiaGlzdG9sb2d5X0hhbnNfQl9XSE9fMjAxNSIsICJnZW5kZXIiLCAic21va2UiKV0sIGJ5ID0gInJvdy5uYW1lcyIsIGFsbC54ID0gVFJVRSkKCmZpZzViLmN1dF9jbGluIDwtIGFzLmRhdGEuZnJhbWUoZmlnNWIuY3V0X2NsaW4sIHJvdy5uYW1lcyA9IGZpZzViLmN1dF9jbGluJFJvdy5uYW1lcykKCmZpZzViLmN1dF9jbGluJFJvdy5uYW1lcyA8LSBOVUxMCgpmaWc1Yi5jdXRfY2xpbl9BQyA8LSBmaWc1Yi5jdXRfY2xpbltmaWc1Yi5jdXRfY2xpbiRoaXN0b2xvZ3lfSGFuc19CX1dIT18yMDE1ID09ICJBQyIsIF0KZmlnNWIuY3V0X2NsaW5fU3FDQyA8LSBmaWc1Yi5jdXRfY2xpbltmaWc1Yi5jdXRfY2xpbiRoaXN0b2xvZ3lfSGFuc19CX1dIT18yMDE1ID09ICJTcUNDIiwgXQoKZmlnNWIuY3V0X2NsaW4KCmZpZzViLmN1dF9jbGluW2ZpZzViLmN1dF9jbGluJGBHaW5pIGluZGV4YCA+PSAwLjI1NDMxLCAiZ2luaUdyb3VwIl0gPC0gIkFib3ZlIG1lZGlhbiIKZmlnNWIuY3V0X2NsaW5bZmlnNWIuY3V0X2NsaW4kYEdpbmkgaW5kZXhgIDwgMC4yNTQzMSwgImdpbmlHcm91cCJdIDwtICJVbmRlciBtZWRpYW4iCmZpZzViLmN1dF9jbGluJGdpbmlHcm91cCA9IGZhY3RvcihmaWc1Yi5jdXRfY2xpbiRnaW5pR3JvdXAsIGxldmVscyA9IGMoIkFib3ZlIG1lZGlhbiIsICJVbmRlciBtZWRpYW4iKSkKYGBgCgojIyBjbHVzdGVyIHdpdGhvdXQgZ2luaSBpbmRleAoKYGBge3J9CnBoZWF0bWFwKHQoaWhjSGVhdFRfdHVtb3Jfbm9ybTJbLCgyOjI1KV0pLCBjbHVzdGVyaW5nX21ldGhvZCA9ICJ3YXJkLkQyIiwKICAgICAgICAgICAgICAgICAgY2x1c3RlcmluZ19kaXN0YW5jZV9yb3dzID0gImV1Y2xpZGVhbiIsIGNsdXN0ZXJpbmdfZGlzdGFuY2VfY29scyA9ICJldWNsaWRlYW4iLAogICAgICAgICAgICAgICAgICBjdXRyZWVfY29scyA9IDMsCiAgICAgICAgICAgICAgICAgICNjb2xvciA9IGNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbChuID0gNywgbmFtZSA9ICJZbEduQnUiKSkoMTAwKSwKICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbl9jb2wgPSBpaGNBbm5vLAogICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uX2NvbG9ycyA9IGloY0Fubm9fY29sb3IsCiAgICAgICAgICAgICAgICAgIGZvbnRzaXplID0gNSwKICAgICAgICAgICAgICAgICAgc2hvd19jb2xuYW1lcyA9IEYKICAgICAgICAgICAgICAgICAgKQoKcGhlYXRtYXAodChpaGNIZWF0VF90dW1vcl9ub3JtM1ssZ3JlcCgiX1MiLCBjb2xuYW1lcyhpaGNIZWF0VF90dW1vcl9ub3JtMykpXSksIGNsdXN0ZXJpbmdfbWV0aG9kID0gIndhcmQuRDIiLAogICAgICAgICAgY2x1c3RlcmluZ19kaXN0YW5jZV9yb3dzID0gImV1Y2xpZGVhbiIsIGNsdXN0ZXJpbmdfZGlzdGFuY2VfY29scyA9ICJldWNsaWRlYW4iLAogICAgICAgICAgY3V0cmVlX2NvbHMgPSAzLAogICAgICAgICAgI2NvbG9yID0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKG4gPSA3LCBuYW1lID0gIllsR25CdSIpKSgxMDApLAogICAgICAgICAgYW5ub3RhdGlvbl9jb2wgPSBpaGNBbm5vLAogICAgICAgICAgYW5ub3RhdGlvbl9jb2xvcnMgPSBpaGNBbm5vX2NvbG9yLAogICAgICAgICAgZm9udHNpemUgPSA1LAogICAgICAgICAgc2hvd19jb2xuYW1lcyA9IEYKKQpwaGVhdG1hcCh0KGloY0hlYXRUX3R1bW9yX25vcm0zWyxncmVwKCJfUyIsIGNvbG5hbWVzKGloY0hlYXRUX3R1bW9yX25vcm0zKSldKSwgY2x1c3RlcmluZ19tZXRob2QgPSAid2FyZC5EMiIsCiAgICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX3Jvd3MgPSAiZXVjbGlkZWFuIiwgY2x1c3RlcmluZ19kaXN0YW5jZV9jb2xzID0gImV1Y2xpZGVhbiIsCiAgICAgICAgICBjdXRyZWVfY29scyA9IDMsCiAgICAgICAgICAjY29sb3IgPSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwobiA9IDcsIG5hbWUgPSAiWWxHbkJ1IikpKDEwMCksCiAgICAgICAgICBhbm5vdGF0aW9uX2NvbCA9IGloY0Fubm8sCiAgICAgICAgICBhbm5vdGF0aW9uX2NvbG9ycyA9IGloY0Fubm9fY29sb3IsCiAgICAgICAgICBmb250c2l6ZSA9IDUsCiAgICAgICAgICBzaG93X2NvbG5hbWVzID0gRgopCnBoZWF0bWFwKHQoaWhjSGVhdFRfdHVtb3Jfbm9ybTNbLGdyZXAoIl9UIiwgY29sbmFtZXMoaWhjSGVhdFRfdHVtb3Jfbm9ybTMpKV0pLCBjbHVzdGVyaW5nX21ldGhvZCA9ICJ3YXJkLkQyIiwKICAgICAgICAgIGNsdXN0ZXJpbmdfZGlzdGFuY2Vfcm93cyA9ICJldWNsaWRlYW4iLCBjbHVzdGVyaW5nX2Rpc3RhbmNlX2NvbHMgPSAiZXVjbGlkZWFuIiwKICAgICAgICAgIGN1dHJlZV9jb2xzID0gMiwKICAgICAgICAgICNjb2xvciA9IGNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbChuID0gNywgbmFtZSA9ICJZbEduQnUiKSkoMTAwKSwKICAgICAgICAgIGFubm90YXRpb25fY29sID0gaWhjQW5ubywKICAgICAgICAgIGFubm90YXRpb25fY29sb3JzID0gaWhjQW5ub19jb2xvciwKICAgICAgICAgIGZvbnRzaXplID0gNSwKICAgICAgICAgIHNob3dfY29sbmFtZXMgPSBGCikKYGBgCgpgYGB7cn0KZmlnNWRfVCA8LSBwaGVhdG1hcCh0KGloY0hlYXRUX3R1bW9yX25vcm0zWyxncmVwKCJfVCIsIGNvbG5hbWVzKGloY0hlYXRUX3R1bW9yX25vcm0zKSldKSwgY2x1c3RlcmluZ19tZXRob2QgPSAid2FyZC5EMiIsCiAgICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX3Jvd3MgPSAiZXVjbGlkZWFuIiwgY2x1c3RlcmluZ19kaXN0YW5jZV9jb2xzID0gImV1Y2xpZGVhbiIsCiAgICAgICAgICBjdXRyZWVfY29scyA9IDIsCiAgICAgICAgICAjY29sb3IgPSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwobiA9IDcsIG5hbWUgPSAiWWxHbkJ1IikpKDEwMCksCiAgICAgICAgICBhbm5vdGF0aW9uX2NvbCA9IGloY0Fubm8sCiAgICAgICAgICBhbm5vdGF0aW9uX2NvbG9ycyA9IGloY0Fubm9fY29sb3IsCiAgICAgICAgICBmb250c2l6ZSA9IDUsCiAgICAgICAgICBzaG93X2NvbG5hbWVzID0gRgopCmZpZzVkX1QKYGBgCgpgYGB7cn0KZmlnNWRfVC5jbHVzdGVyIDwtIGZpZzVkX1QkdHJlZV9jb2wKCmZpZzVkX1QuY2x1c3Rlci5wbG90IDwtIHBsb3QoZmlnNWRfVC5jbHVzdGVyLCBoYW5nID0gLTEsIGNleD0wLjYsIGF4ZXM9RkFMU0UsIGFubj1GQUxTRSkKCmZpZzVkX1QuY3V0IDwtIGN1dHJlZShmaWc1ZF9ULmNsdXN0ZXIsIDIpCgpmaWc1ZF9ULmN1dF8xIDwtIG5hbWVzKGZpZzVkX1QuY3V0KVtmaWc1ZF9ULmN1dCA9PSAxXQpmaWc1ZF9ULmN1dF8yIDwtIG5hbWVzKGZpZzVkX1QuY3V0KVtmaWc1ZF9ULmN1dCA9PSAyXQoKZmlnNWRfVC5jdXRfZ2luaSA8LSBtZXJnZShBQl9HaW5pX2Fubm8sIGZpZzVkX1QuY3V0LCBieSA9ICJyb3cubmFtZXMiLCBhbGwueSA9IFRSVUUpCgpmaWc1ZF9ULmN1dF9naW5pIDwtIGFzLmRhdGEuZnJhbWUoZmlnNWRfVC5jdXRfZ2luaSwgcm93Lm5hbWVzID0gZmlnNWRfVC5jdXRfZ2luaSRSb3cubmFtZXMpCgpmaWc1ZF9ULmN1dF9naW5pJFJvdy5uYW1lcyA8LSBOVUxMCgpmaWc1ZF9ULmN1dF9naW5pIDwtIHJlbmFtZShmaWc1ZF9ULmN1dF9naW5pLCBjKCJDbHVzdGVyIj0ieSIpKQpgYGAKCmBgYHtyfQpmaWc1ZF9ULmN1dF9naW5pW2ZpZzVkX1QuY3V0X2dpbmkkQ2x1c3RlciA9PSAxLCAiQ2xhc3MiXSA8LSAiSW1tdW5lIGNvbGQiCmZpZzVkX1QuY3V0X2dpbmlbZmlnNWRfVC5jdXRfZ2luaSRDbHVzdGVyID09IDIsICJDbGFzcyJdIDwtICJJbW11bmUgaG90IgpmaWc1ZF9ULmN1dF9naW5pJENsYXNzID0gZmFjdG9yKGZpZzVkX1QuY3V0X2dpbmkkQ2xhc3MsIGxldmVscyA9IGMoIkltbXVuZSBob3QiLCAiSW1tdW5lIGNvbGQiKSkKYGBgCgpgYGB7cn0KZmlnNWRfVC5jdXRfZ2luaSA8LSBhcy5kYXRhLmZyYW1lKGZpZzVkX1QuY3V0X2dpbmkpCmZpZzVkX1QuY3V0X2dpbmkgPC0gcmVuYW1lKGZpZzVkX1QuY3V0X2dpbmksIGMoIkdpbmlJbmRleCI9IkdpbmkgaW5kZXgiKSkKY29tcGFyZV9tZWFucyhHaW5pSW5kZXggfiBDbGFzcywgZGF0YSA9IGZpZzVkX1QuY3V0X2dpbmkpCmBgYAoKYGBge3J9CmZpZzVkX1QuYm94IDwtIGdncGxvdChmaWc1ZF9ULmN1dF9naW5pLCBhZXMoeCA9IENsYXNzLCB5ID0gR2luaUluZGV4LCBmaWxsPUNsYXNzKSkgKwogICAgZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3VyID0gImJsYWNrIiwgb3V0bGllci5zaGFwZSA9IDE2LCBvdXRsaWVyLnNpemUgPSAyLCBjb2xvdXIgPSAiYmxhY2siKSArCiAgICB0aGVtZV9jbGFzc2ljKCkgKwogICAgIyBjb29yZF9mbGlwKCkgKwogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI2U2NGIzNSIsICIjNGRiYmQ1IikpICsKICAgIGxhYnModGl0bGUgPSAiQ2xhc3MiLCB4ID0gIkNsYXNzIikgKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkgKwogICAgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IE5VTEwpCgpmaWc1ZF9ULmJveApgYGAKCmBgYHtyfQpmaWc1ZF9ULmN1dF9rbSA8LSBtZXJnZShmaWc1ZF9ULmN1dF9naW5pLCBHaW5pQ2xpbl90dW1vclssIGMoIk9TX3llYXJzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjkiLCAic3RhdHVzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjkiKV0sIGJ5ID0gInJvdy5uYW1lcyIpCmZpZzVkX1QuY3V0X2ttIDwtIGFzLmRhdGEuZnJhbWUoZmlnNWRfVC5jdXRfa20sIHJvdy5uYW1lcyA9IGZpZzVkX1QuY3V0X2ttJFJvdy5uYW1lcykKZmlnNWRfVC5jdXRfa20kUm93Lm5hbWVzIDwtIE5VTEwKCmZpZzVkX1QudGVzdCA8LSBzdXJ2Zml0KFN1cnYoT1NfeWVhcnNfNV95ZWFyc190cnVua18yMDE5MDMyOSwgc3RhdHVzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjkpIH4gQ2xhc3MsIGRhdGEgPSBmaWc1ZF9ULmN1dF9rbSkKCnN1bW1hcnkoZmlnNWRfVC50ZXN0KSR0YWJsZQpgYGAKCmBgYHtyfQpnZ3N1cnZwbG90KGZpZzVkX1QudGVzdCwKICAgICAgICAgcHZhbCA9IFRSVUUsCiAgICAgICAgIHBhbGV0dGUgPSBjKCIjZTY0YjM1IiwgIiM0ZGJiZDUiLCAiIzk5OTk5OSIpLAogICAgICAgICBicmVhay50aW1lLmJ5ID0gMSwKICAgICAgICAgZ2d0aGVtZSA9IHRoZW1lX2NsYXNzaWMoKSwKICAgICAgICAgI2xlZ2VuZC5sYWJzID0gYygiQWJvdmUgbWVkaWFuIiwgIlVuZGVyIG1lZGlhbiIpLAogICAgICAgICByaXNrLnRhYmxlID0gImFic19wY3QiLAogICAgICAgICByaXNrLnRhYmxlLnkudGV4dCA9IEZBTFNFLAogICAgICAgICB4bGFiID0gIlRpbWUgKHllYXJzKSIsCiAgICAgICAgIHRpdGxlID0gImdpbmlTdXJ2X0NsYXNzIiwKICAgICAgICAgeGxpbSA9IGMoMCw1LjIpLAogICAgICAgICBheGVzLm9mZnNldCA9IEZBTFNFLAogICAgICAgICByaXNrLnRhYmxlLmZvbnRzaXplID0gMi41LAogICAgICAgICBsZWdlbmQgPSBjKDAuOSwwLjkpLAogICAgICAgICByaXNrLnRhYmxlLnRpdGxlID0gIk51bWJlciBhdCByaXNrIGJ5IHRpbWU6IG4gKCUpIiwKICAgICAgICAgZm9udC5tYWluID0gYygpKQpgYGAKCgpgYGB7cn0KZmlnNWRfUyA8LSBwaGVhdG1hcCh0KGloY0hlYXRUX3R1bW9yX25vcm0zWyxncmVwKCJfUyIsIGNvbG5hbWVzKGloY0hlYXRUX3R1bW9yX25vcm0zKSldKSwgY2x1c3RlcmluZ19tZXRob2QgPSAid2FyZC5EMiIsCiAgICAgICAgY2x1c3RlcmluZ19kaXN0YW5jZV9yb3dzID0gImV1Y2xpZGVhbiIsIGNsdXN0ZXJpbmdfZGlzdGFuY2VfY29scyA9ICJldWNsaWRlYW4iLAogICAgICAgIGN1dHJlZV9jb2xzID0gMywKICAgICAgICAjY29sb3IgPSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwobiA9IDcsIG5hbWUgPSAiWWxHbkJ1IikpKDEwMCksCiAgICAgICAgYW5ub3RhdGlvbl9jb2wgPSBpaGNBbm5vLAogICAgICAgIGFubm90YXRpb25fY29sb3JzID0gaWhjQW5ub19jb2xvciwKICAgICAgICBmb250c2l6ZSA9IDUsCiAgICAgICAgc2hvd19jb2xuYW1lcyA9IEYKKQpmaWc1ZF9TCmBgYAoKYGBge3J9CmZpZzVkX1MuY2x1c3RlciA8LSBmaWc1ZF9TJHRyZWVfY29sCgpmaWc1ZF9TLmNsdXN0ZXIucGxvdCA8LSBwbG90KGZpZzVkX1MuY2x1c3RlciwgaGFuZyA9IC0xLCBjZXg9MC42LCBheGVzPUZBTFNFLCBhbm49RkFMU0UpCgpmaWc1ZF9TLmN1dCA8LSBjdXRyZWUoZmlnNWRfUy5jbHVzdGVyLCAzKQoKZmlnNWRfUy5jdXRfMSA8LSBuYW1lcyhmaWc1ZF9TLmN1dClbZmlnNWRfUy5jdXQgPT0gMV0KZmlnNWRfUy5jdXRfMiA8LSBuYW1lcyhmaWc1ZF9TLmN1dClbZmlnNWRfUy5jdXQgPT0gMl0KZmlnNWRfUy5jdXRfMyA8LSBuYW1lcyhmaWc1ZF9TLmN1dClbZmlnNWRfUy5jdXQgPT0gM10KCmZpZzVkX1MuY3V0X2dpbmkgPC0gbWVyZ2UoQUJfR2luaV9hbm5vLCBmaWc1ZF9TLmN1dCwgYnkgPSAicm93Lm5hbWVzIiwgYWxsLnkgPSBUUlVFKQoKZmlnNWRfUy5jdXRfZ2luaSA8LSBhcy5kYXRhLmZyYW1lKGZpZzVkX1MuY3V0X2dpbmksIHJvdy5uYW1lcyA9IGZpZzVkX1MuY3V0X2dpbmkkUm93Lm5hbWVzKQoKZmlnNWRfUy5jdXRfZ2luaSRSb3cubmFtZXMgPC0gTlVMTAoKZmlnNWRfUy5jdXRfZ2luaSA8LSByZW5hbWUoZmlnNWRfUy5jdXRfZ2luaSwgYygiQ2x1c3RlciI9InkiKSkKYGBgCgpgYGB7cn0KZmlnNWRfUy5jdXRfZ2luaVtmaWc1ZF9TLmN1dF9naW5pJENsdXN0ZXIgPT0gMSwgIkNsYXNzIl0gPC0gIkltbXVuZSBjb2xkIgpmaWc1ZF9TLmN1dF9naW5pW2ZpZzVkX1MuY3V0X2dpbmkkQ2x1c3RlciA9PSAyLCAiQ2xhc3MiXSA8LSAiTWVkaWFuIgpmaWc1ZF9TLmN1dF9naW5pW2ZpZzVkX1MuY3V0X2dpbmkkQ2x1c3RlciA9PSAzLCAiQ2xhc3MiXSA8LSAiSW1tdW5lIGhvdCIKZmlnNWRfUy5jdXRfZ2luaSRDbGFzcyA9IGZhY3RvcihmaWc1ZF9TLmN1dF9naW5pJENsYXNzLCBsZXZlbHMgPSBjKCJJbW11bmUgaG90IiwgIk1lZGlhbiIsICJJbW11bmUgY29sZCIpKQpgYGAKCmBgYHtyfQpmaWc1ZF9TLmN1dF9naW5pIDwtIGFzLmRhdGEuZnJhbWUoZmlnNWRfUy5jdXRfZ2luaSkKZmlnNWRfUy5jdXRfZ2luaSA8LSByZW5hbWUoZmlnNWRfUy5jdXRfZ2luaSwgYygiR2luaUluZGV4Ij0iR2luaSBpbmRleCIpKQpjb21wYXJlX21lYW5zKEdpbmlJbmRleCB+IENsYXNzLCBkYXRhID0gZmlnNWRfUy5jdXRfZ2luaSkKYGBgCgpgYGB7cn0KZmlnNWRfUy5ib3ggPC0gZ2dwbG90KGZpZzVkX1MuY3V0X2dpbmksIGFlcyh4ID0gQ2xhc3MsIHkgPSBHaW5pSW5kZXgsIGZpbGw9Q2xhc3MpKSArCiAgICBnZW9tX2JveHBsb3Qob3V0bGllci5jb2xvdXIgPSAiYmxhY2siLCBvdXRsaWVyLnNoYXBlID0gMTYsIG91dGxpZXIuc2l6ZSA9IDIsIGNvbG91ciA9ICJibGFjayIpICsKICAgIHRoZW1lX2NsYXNzaWMoKSArCiAgICAjIGNvb3JkX2ZsaXAoKSArCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjZTY0YjM1IiwgIiM0ZGJiZDUiLCAiIzk5OTk5OSIpKSArCiAgICBsYWJzKHRpdGxlID0gIkNsYXNzIiwgeCA9ICJDbGFzcyIpICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpICsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBOVUxMKQpgYGAKCmBgYHtyfQpmaWc1ZF9TLmN1dF9rbSA8LSBtZXJnZShmaWc1ZF9TLmN1dF9naW5pLCBHaW5pQ2xpbl90dW1vclssIGMoIk9TX3llYXJzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjkiLCAic3RhdHVzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjkiKV0sIGJ5ID0gInJvdy5uYW1lcyIpCmZpZzVkX1MuY3V0X2ttIDwtIGFzLmRhdGEuZnJhbWUoZmlnNWRfUy5jdXRfa20sIHJvdy5uYW1lcyA9IGZpZzVkX1MuY3V0X2ttJFJvdy5uYW1lcykKZmlnNWRfUy5jdXRfa20kUm93Lm5hbWVzIDwtIE5VTEwKCmZpZzVkX1MudGVzdCA8LSBzdXJ2Zml0KFN1cnYoT1NfeWVhcnNfNV95ZWFyc190cnVua18yMDE5MDMyOSwgc3RhdHVzXzVfeWVhcnNfdHJ1bmtfMjAxOTAzMjkpIH4gQ2xhc3MsIGRhdGEgPSBmaWc1ZF9TLmN1dF9rbSkKCnN1bW1hcnkoZmlnNWRfUy50ZXN0KSR0YWJsZQpgYGAKCmBgYHtyfQpnZ3N1cnZwbG90KGZpZzVkX1MudGVzdCwKICAgICAgICAgcHZhbCA9IFRSVUUsCiAgICAgICAgIHBhbGV0dGUgPSBjKCIjZTY0YjM1IiwgIiM0ZGJiZDUiLCAiIzk5OTk5OSIpLAogICAgICAgICBicmVhay50aW1lLmJ5ID0gMSwKICAgICAgICAgZ2d0aGVtZSA9IHRoZW1lX2NsYXNzaWMoKSwKICAgICAgICAgI2xlZ2VuZC5sYWJzID0gYygiQWJvdmUgbWVkaWFuIiwgIlVuZGVyIG1lZGlhbiIpLAogICAgICAgICByaXNrLnRhYmxlID0gImFic19wY3QiLAogICAgICAgICByaXNrLnRhYmxlLnkudGV4dCA9IEZBTFNFLAogICAgICAgICB4bGFiID0gIlRpbWUgKHllYXJzKSIsCiAgICAgICAgIHRpdGxlID0gImdpbmlTdXJ2X0NsYXNzIiwKICAgICAgICAgeGxpbSA9IGMoMCw1LjIpLAogICAgICAgICBheGVzLm9mZnNldCA9IEZBTFNFLAogICAgICAgICByaXNrLnRhYmxlLmZvbnRzaXplID0gMi41LAogICAgICAgICBsZWdlbmQgPSBjKDAuOSwwLjkpLAogICAgICAgICByaXNrLnRhYmxlLnRpdGxlID0gIk51bWJlciBhdCByaXNrIGJ5IHRpbWU6IG4gKCUpIiwKICAgICAgICAgZm9udC5tYWluID0gYygpKQpgYGAKCgpgYGB7cn0KaWhjSGVhdFRfdHVtb3Jfbm9ybTQgPC0gaWhjSGVhdFQubm9ybTNbcm93bmFtZXMoaWhjSGVhdFRfdHVtb3Jfbm9ybTIpLGdyZXAoIlNBbmRUTSIsIGNvbG5hbWVzKGloY0hlYXRULm5vcm0zKSldCgppaGNIZWF0VF90dW1vcl9ub3JtNCA8LSBtZXJnZShBQl9HaW5pX2Fubm8sIGloY0hlYXRUX3R1bW9yX25vcm00LCBieT0icm93Lm5hbWVzIiwgYWxsPUZBTFNFKQoKaWhjSGVhdFRfdHVtb3Jfbm9ybTQgPC0gYXMuZGF0YS5mcmFtZShpaGNIZWF0VF90dW1vcl9ub3JtNCwgcm93Lm5hbWVzID0gaWhjSGVhdFRfdHVtb3Jfbm9ybTQkUm93Lm5hbWVzKQppaGNIZWF0VF90dW1vcl9ub3JtNCRSb3cubmFtZXMgPC0gTlVMTAoKaWhjSGVhdFRfdHVtb3Jfbm9ybTQgPC0gcmVuYW1lKGloY0hlYXRUX3R1bW9yX25vcm00LCBjKCJHaW5pSW5kZXgiPSJHaW5pIGluZGV4IikpCgppaGNIZWF0VF90dW1vcl9ub3JtNCA8LSBpaGNIZWF0VF90dW1vcl9ub3JtNCAlPiUgcmVuYW1lX3dpdGgofiBnc3ViKCJTUTEiLCAiXyIsLngpKQoKaWhjSGVhdFRfdHVtb3Jfbm9ybTQgPC0gaWhjSGVhdFRfdHVtb3Jfbm9ybTRbLGdyZXAoIkNENDQiLCBjb2xuYW1lcyhpaGNIZWF0VF90dW1vcl9ub3JtNCksIGludmVydCA9IFRSVUUpXQpgYGAKCmBgYHtyfQpmaWc1ZF9TVCA8LSBwaGVhdG1hcCh0KGloY0hlYXRUX3R1bW9yX25vcm00WyxjKDI6MTIpXSksIGNsdXN0ZXJpbmdfbWV0aG9kID0gIndhcmQuRDIiLAogICAgICAgIGNsdXN0ZXJpbmdfZGlzdGFuY2Vfcm93cyA9ICJldWNsaWRlYW4iLCBjbHVzdGVyaW5nX2Rpc3RhbmNlX2NvbHMgPSAiZXVjbGlkZWFuIiwKICAgICAgICBjdXRyZWVfY29scyA9IDIsCiAgICAgICAgI2NvbG9yID0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKG4gPSA3LCBuYW1lID0gIllsR25CdSIpKSgxMDApLAogICAgICAgIGFubm90YXRpb25fY29sID0gaWhjQW5ubywKICAgICAgICBhbm5vdGF0aW9uX2NvbG9ycyA9IGloY0Fubm9fY29sb3IsCiAgICAgICAgZm9udHNpemUgPSA1LAogICAgICAgIHNob3dfY29sbmFtZXMgPSBGKQoKZmlnNWRfU1QKYGBgCgpgYGB7cn0KZmlnNWRfU1QuY2x1c3RlciA8LSBmaWc1ZF9TVCR0cmVlX2NvbAoKZmlnNWRfU1QuY2x1c3Rlci5wbG90IDwtIHBsb3QoZmlnNWRfU1QuY2x1c3RlciwgaGFuZyA9IC0xLCBjZXg9MC42LCBheGVzPUZBTFNFLCBhbm49RkFMU0UpCgojcGxvdChmaWc1ZF9TVC5jbHVzdGVyLCBoYW5nID0gLTEsIGNleD0wLjYsIGF4ZXM9RkFMU0UsIGFubj1GQUxTRSkKCmZpZzVkX1NULmN1dCA8LSBjdXRyZWUoZmlnNWRfU1QuY2x1c3RlciwgMikKCmZpZzVkX1NULmN1dF8xIDwtIG5hbWVzKGZpZzVkX1NULmN1dClbZmlnNWRfU1QuY3V0ID09IDFdCmZpZzVkX1NULmN1dF8yIDwtIG5hbWVzKGZpZzVkX1NULmN1dClbZmlnNWRfU1QuY3V0ID09IDJdCgpmaWc1ZF9TVC5jdXRfZ2luaSA8LSBtZXJnZShBQl9HaW5pX2Fubm8sIGZpZzVkX1NULmN1dCwgYnkgPSAicm93Lm5hbWVzIiwgYWxsLnkgPSBUUlVFKQoKZmlnNWRfU1QuY3V0X2dpbmkgPC0gYXMuZGF0YS5mcmFtZShmaWc1ZF9TVC5jdXRfZ2luaSwgcm93Lm5hbWVzID0gZmlnNWRfU1QuY3V0X2dpbmkkUm93Lm5hbWVzKQoKZmlnNWRfU1QuY3V0X2dpbmkkUm93Lm5hbWVzIDwtIE5VTEwKCmZpZzVkX1NULmN1dF9naW5pIDwtIHJlbmFtZShmaWc1ZF9TVC5jdXRfZ2luaSwgYygiQ2x1c3RlciI9InkiKSkKYGBgCgpgYGB7cn0KZmlnNWRfU1QuY3V0X2dpbmlbZmlnNWRfU1QuY3V0X2dpbmkkQ2x1c3RlciA9PSAxLCAiQ2xhc3MiXSA8LSAiSW1tdW5lIGNvbGQiCmZpZzVkX1NULmN1dF9naW5pW2ZpZzVkX1NULmN1dF9naW5pJENsdXN0ZXIgPT0gMiwgIkNsYXNzIl0gPC0gIkltbXVuZSBob3QiCmZpZzVkX1NULmN1dF9naW5pJENsYXNzID0gZmFjdG9yKGZpZzVkX1NULmN1dF9naW5pJENsYXNzLCBsZXZlbHMgPSBjKCJJbW11bmUgaG90IiwgIkltbXVuZSBjb2xkIikpCmBgYAoKYGBge3J9CmZpZzVkX1NULmN1dF9naW5pIDwtIGFzLmRhdGEuZnJhbWUoZmlnNWRfU1QuY3V0X2dpbmkpCmZpZzVkX1NULmN1dF9naW5pIDwtIHJlbmFtZShmaWc1ZF9TVC5jdXRfZ2luaSwgYygiR2luaUluZGV4Ij0iR2luaSBpbmRleCIpKQpjb21wYXJlX21lYW5zKEdpbmlJbmRleCB+IENsYXNzLCBkYXRhID0gZmlnNWRfU1QuY3V0X2dpbmkpCmBgYAoKYGBge3J9CmZpZzVkX1NULmJveCA8LSBnZ3Bsb3QoZmlnNWRfU1QuY3V0X2dpbmksIGFlcyh4ID0gQ2xhc3MsIHkgPSBHaW5pSW5kZXgsIGZpbGw9Q2xhc3MpKSArCiAgICBnZW9tX2JveHBsb3Qob3V0bGllci5jb2xvdXIgPSAiYmxhY2siLCBvdXRsaWVyLnNoYXBlID0gMTYsIG91dGxpZXIuc2l6ZSA9IDIsIGNvbG91ciA9ICJibGFjayIpICsKICAgIHRoZW1lX2NsYXNzaWMoKSArCiAgICAjIGNvb3JkX2ZsaXAoKSArCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjZTY0YjM1IiwgIiM0ZGJiZDUiLCAiIzk5OTk5OSIpKSArCiAgICBsYWJzKHRpdGxlID0gIkNsYXNzIiwgeCA9ICJDbGFzcyIpICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpICsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBOVUxMKQpmaWc1ZF9TVC5ib3gKYGBgCiMjIE9yZGVyZWQgYnkgR2luaQpgYGB7cn0KcGhlYXRtYXAodChpaGNIZWF0VF90dW1vcl9ub3JtNFtvcmRlcihpaGNIZWF0VF90dW1vcl9ub3JtNCRHaW5pSW5kZXgpLGMoMjoxMildKSwKICAgICAgICAgI2NsdXN0ZXJpbmdfbWV0aG9kID0gIndhcmQuRDIiLAogICAgICAgICBjbHVzdGVyX3Jvd3MgPSBGLCBjbHVzdGVyX2NvbHMgPSBGLAogICAgICAgICBjdXRyZWVfY29scyA9IDIsCiAgICAgICAgICNjb2xvciA9IGNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbChuID0gNywgbmFtZSA9ICJZbEduQnUiKSkoMTAwKSwKICAgICAgICAgYW5ub3RhdGlvbl9jb2wgPSBpaGNBbm5vLAogICAgICAgICBhbm5vdGF0aW9uX2NvbG9ycyA9IGloY0Fubm9fY29sb3IsCiAgICAgICAgIGZvbnRzaXplID0gOCwKICAgICAgICAgc2hvd19jb2xuYW1lcyA9IEYpCmBgYAoKIyBJSEMgY29ycmVsYXRpb24gcGxvdAoKYGBge3J9CmZpZzYgPC0gY29ycnBsb3QoZGF0YS5tYXRyaXgoaWhjQ29yUiksIG1ldGhvZCA9ICJjaXJjbGUiLGNvbCA9IHJldihDT0wyKCdSZEJ1JywgMjAwKSksCiAgICAgICAgICAgICAgICAgcC5tYXQgPSBkYXRhLm1hdHJpeChpaGNDb3JQKSwgaW5zaWcgPSAibGFiZWxfc2lnIiwgc2lnLmxldmVsID0gYyguMDAxLCAuMDEsIC4wNSksIHBjaC5jZXggPSAwLjgsCiAgICAgICAgICAgICAgICAgdGwuY29sID0gImJsYWNrIikKZmlnNgpgYGAKCmBgYHtyfQppaGNDb3JQX21lbHQgPC0gYXMuZGF0YS5mcmFtZShpaGNDb3JQX21lbHQpCmloY0NvclBfbWVsdCR2YXIxIDwtIGZhY3RvcihpaGNDb3JQX21lbHQkdmFyMSwgbGV2ZWxzID0gYygiQ0QzIiwiQ0Q0IiwiQ0Q4IiwiQ0QyMCIsIkNENDQiLCJDRDQ1Uk8iLCJDRDEzOCIsIkNEMTYzIiwiRk9YUDMiLCJOS3A0NiIsIlBEMSIsIlBETDEiKSkKaWhjQ29yUF9tZWx0JHZhcjIgPC0gZmFjdG9yKGloY0NvclBfbWVsdCR2YXIyLCBsZXZlbHMgPSBjKCJTQW5kVCIsIlR1bW9yIiwgIlN0cm9tYSIpKQoKZmlnNmIgPC0gZ2dwbG90KGloY0NvclBfbWVsdCwgYWVzKHZhcjEsIHZhcjIsIGZpbGwgPSBDb3JyKSkgKwogIGdlb21fcG9pbnQoc2hhcGU9MjEsIGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAxMikrCiAgdGhlbWVfY2xhc3NpYygpKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGNvbG91cnMgPSByZXYoYnJld2VyLnBhbCg1LCAiU3BlY3RyYWwiKSkpKwogIGxhYnModGl0bGUgPSAiQ29ycmVsYXRpb24iLCB4ID0gIklIQyBtYXJrZXIiLCB5ID0gIlBvc2l0aW9uIikgKwogIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSkrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGxhYmVsKSwgc2l6ZSA9IDUsIGNvbG91ciA9ICJibGFjayIpCgpmaWc2YgpgYGAKCgojIEZpZ3VyZSA5IEx5bXBob3RyYWNrIGNsdXN0ZXIgcGxvdAoKIyMgTDQ4MQpgYGB7cn0KTDQ4MV9MIDwtIGFzLmRhdGEuZnJhbWUoTDQ4MV9MKQoKTDQ4MV9SIDwtIGFzLmRhdGEuZnJhbWUoTDQ4MV9SKQoKTDQ4MV9hbGwgPC0gYXMuZGF0YS5mcmFtZShMNDgxX2FsbCkKCkw0ODFfTFsiQ2xhc3MiXSA8LSAiTHltcGhvdHJhY2siCgpMNDgxX1JbIkNsYXNzIl0gPC0gIlJOQXNlcSIKYGBgCgpgYGB7cn0KbnBqLnBhbCA9IHBhbF9ucGcoIm5yYyIsIGFscGhhID0gMC45KSgxMCkKc2ltcC5wYWwgPSBwYWxfc2ltcHNvbnMoInNwcmluZ2ZpZWxkIikoMTYpCm5lam0ucGFsID0gcGFsX25lam0oImRlZmF1bHQiLCBhbHBoYSA9IDAuOSkoOCkKamFtYS5wYWwgPSBwYWxfamFtYSgiZGVmYXVsdCIsYWxwaGEgPSAwLjkpKDcpCmZpZzlfcGFsID0gYyhjKCIjRTBFM0UzRkYiKSwgbnBqLnBhbCwgc2ltcC5wYWwsIG5lam0ucGFsLCBqYW1hLnBhbCkKCmZpZzlfTDQ4MSA8LSBnZ3Bsb3QoTDQ4MV9hbGwsIGFlcyh4PSBUeXBlLCB5PSBGcmFjdGlvbiwgZmlsbD0gQ2xvbmUpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAic3RhY2siLCB3aWR0aCA9IDAuNikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGZpZzlfcGFsKSArCiAgc2NhbGVfeV9icmVhayhjKDQwLDk1KSwgc2NhbGVzID0gMC4yLCB0aWNrbGFiZWxzID0gYyg5NSwxMDApKQoKCmdnLmdhcChwbG90ID0gZmlnOV9MNDgxLAogICAgICAgc2VnbWVudHMgPSBjKDQwLDgwKSwKICAgICAgIHlsaW0gPSBjKDAsIDEwMCksCiAgICAgICB0aWNrX3dpZHRoID0gYyg1LCAxMCksCiAgICAgICByZWxfaGVpZ2h0cyA9IGMoMC4zLCAwLCAwLjEpCiAgICAgICApCgpnZ3Bsb3QoTDQ4MV9MLCBhZXMoeD1DbGFzcywgeT0gRnJhY3Rpb24sIGZpbGw9IHJlb3JkZXIoTHltcGhvdHJhY2ssIC1GcmFjdGlvbikpKSArCiAgICAgZ2VvbV9jb2wocG9zaXRpb24gPSAic3RhY2siLCB3aWR0aCA9IDAuNikgKwogICAgIHRoZW1lX2NsYXNzaWMoKSArCiAgICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gZmlnOV9wYWwpICsKICAgICBzY2FsZV95X2JyZWFrKGMoNyw5MiksIHNjYWxlcyA9IDAuMiwgdGlja2xhYmVscyA9IGMoOTUsMTAwKSwgZXhwYW5kID0gRkFMU0UpICsKICAgICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLDApLCBicmVha3MgPSBjKDAsMiw0LDYpKQoKZ2dwbG90KEw0ODFfUiwgYWVzKHg9Q2xhc3MsIHk9IEZyYWN0aW9uLCBmaWxsPSByZW9yZGVyKFJOQXNlcSwgLUZyYWN0aW9uKSkpICsKICAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICJzdGFjayIsIHdpZHRoID0gMC42KSArCiAgICAgdGhlbWVfY2xhc3NpYygpICsKICAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBmaWc5X3BhbCkgKwogICAgIHNjYWxlX3lfYnJlYWsoYyg0MCw5MiksIHNjYWxlcyA9IDAuMiwgdGlja2xhYmVscyA9IGMoOTUsMTAwKSwgZXhwYW5kID0gRkFMU0UpICsKICAgICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLDApLCBicmVha3MgPSBjKDAsMTAsMjAsMzAsNDApKQoKYGBgCgoKIyBGaWcxMCBWb2Nhbm9sIHBsb3QKCmBgYHtyfQpkaWZmR2VuZSA8LSByZWFkLnRhYmxlKCcvVXNlcnMvaHVpeXU4MTgvUHJvamVjdC9UQ1IvRGlmZmVyZW50aWFsRXhwci9ib21pMl9mdWxsUmVzdWx0LnR4dCcsIHNlcCA9ICJcdCIsIGhlYWRlciA9IFRSVUUsIHJvdy5uYW1lcyA9IDEpCgojIFNvcnQgdGhlIHRhYmxlIGFjY29yZGluZyB0byB0aGUgcGFkaihhZGp1c3RlZCBwLXZhbHVlKSBhc2NlbmRpbmcuCiMgRm9yIGdlbmVzIHdpdGggc2FtZSBwYWRqLCBvcmRlciBhY2NvcmRpbmcgdG8gdGhlIGxvZzJGQyBkZXNjZW5kaW5nLgojIFRoZW4gLCBhdCB0aGUgZW5kIG9mIHRoZSBjb2RpbmcgaXMgZXNzZW5zaWFsCmRpZmZHZW5lIDwtIGRpZmZHZW5lW29yZGVyKGRpZmZHZW5lJHBhZGosIGRpZmZHZW5lJGxvZzJGb2xkQ2hhbmdlLCBkZWNyZWFzaW5nID0gYyhGQUxTRSwgVFJVRSkpLF0KCmxpYnJhcnkoJ2Jpb21hUnQnKQoKbWFydCA8LSB1c2VEYXRhc2V0KCJoc2FwaWVuc19nZW5lX2Vuc2VtYmwiLCB1c2VNYXJ0KCJlbnNlbWJsIikpCgpkaWZmX2dlbmVzX2VpZCA8LSByb3duYW1lcyhkaWZmR2VuZSkKCmRpZmZfZ2VuZXNfR19saXN0IDwtIGdldEJNKGZpbHRlcnM9ImVuc2VtYmxfZ2VuZV9pZCIsIGF0dHJpYnV0ZXM9YygiZW5zZW1ibF9nZW5lX2lkIiwgImhnbmNfc3ltYm9sIiwgImRlc2NyaXB0aW9uIiksIHZhbHVlcz1kaWZmX2dlbmVzX2VpZCwgbWFydD1tYXJ0KQoKIyBkaWZmR2VuZV9oZ25jIDwtIG1lcmdlKGRpZmZHZW5lLCBkaWZmX2dlbmVzX0dfbGlzdCwgYnkueD0icm93Lm5hbWVzIiwgYnkueSA9ICJlbnNlbWJsX2dlbmVfaWQiKQoKIyBUaGUgc2lnbmlmaWNhbnRseSB1cC1yZWd1bGF0ZWQgZ2VuZXMgYXJlIGxhYmVsZWQgd2l0aCAnVVAnCmRpZmZHZW5lW3doaWNoKGRpZmZHZW5lJGxvZzJGb2xkQ2hhbmdlID49IDEgJiBkaWZmR2VuZSRwYWRqIDwgMC4wMSksICdzaWduJ10gPC0gJ1VQJwoKIyBUaGUgc2lnbmlmaWNhbnRseSBkb3duLXJlZ3VsYXRlZCBnZW5lcyBhcmUgbGFiZWxlZCB3aXRoICdET1dOJwpkaWZmR2VuZVt3aGljaChkaWZmR2VuZSRsb2cyRm9sZENoYW5nZSA8PSAtMSAmIGRpZmZHZW5lJHBhZGogPCAwLjAxKSwgJ3NpZ24nXSA8LSAnRE9XTicKCiMgVGhlIHJlc3QgZ2VuZXMgYXJlIGxhYmVsZWQgJ25vbmUnCmRpZmZHZW5lW3doaWNoKGFicyhkaWZmR2VuZSRsb2cyRm9sZENoYW5nZSkgPD0gMSB8IGRpZmZHZW5lJHBhZGogPj0gMC4wMSksICdzaWduJ10gPC0gJ25vbmUnCgpkaWZmR2VuZVsiRU5TRzAwMDAwMTgwNjQ0IiwgImxhYmVsIl0gPC0gIlBSRjEiCmRpZmZHZW5lWyJFTlNHMDAwMDAxMDA0NTMiLCAibGFiZWwiXSA8LSAiR1pNQiIKZGlmZkdlbmVbIkVOU0cwMDAwMDEwMDQ1MCIsICJsYWJlbCJdIDwtICJHWk1IIgpkaWZmR2VuZVsiRU5TRzAwMDAwMTIwMjE3IiwgImxhYmVsIl0gPC0gIlBELUwxIgpkaWZmR2VuZVsiRU5TRzAwMDAwMDg5NjkyIiwgImxhYmVsIl0gPC0gIkxBRzMiCmRpZmZHZW5lWyJFTlNHMDAwMDAxODE4NDciLCAibGFiZWwiXSA8LSAiVElHSVQiCmRpZmZHZW5lW2RpZmZfZ2VuZXNfR19saXN0W2RpZmZfZ2VuZXNfR19saXN0JGhnbmNfc3ltYm9sID09ICJJRk5HIiwiZW5zZW1ibF9nZW5lX2lkIl0sICJsYWJlbCJdIDwtICJJRk5HIgpkaWZmR2VuZVtkaWZmX2dlbmVzX0dfbGlzdFtkaWZmX2dlbmVzX0dfbGlzdCRoZ25jX3N5bWJvbCA9PSAiSUwxN0EiLCJlbnNlbWJsX2dlbmVfaWQiXSwgImxhYmVsIl0gPC0gIklMMTdBIgpkaWZmR2VuZVtkaWZmX2dlbmVzX0dfbGlzdFtkaWZmX2dlbmVzX0dfbGlzdCRoZ25jX3N5bWJvbCA9PSAiTktHNyIsImVuc2VtYmxfZ2VuZV9pZCJdLCAibGFiZWwiXSA8LSAiTktHNyIKZGlmZkdlbmVbZGlmZl9nZW5lc19HX2xpc3RbZGlmZl9nZW5lc19HX2xpc3QkaGduY19zeW1ib2wgPT0gIkZBU0xHIiwiZW5zZW1ibF9nZW5lX2lkIl0sICJsYWJlbCJdIDwtICJGQVNMRyIKZGlmZkdlbmVbZGlmZl9nZW5lc19HX2xpc3RbZGlmZl9nZW5lc19HX2xpc3QkaGduY19zeW1ib2wgPT0gIkdaTUEiLCJlbnNlbWJsX2dlbmVfaWQiXSwgImxhYmVsIl0gPC0gIkdaTUEiCmRpZmZHZW5lW2RpZmZfZ2VuZXNfR19saXN0W2RpZmZfZ2VuZXNfR19saXN0JGhnbmNfc3ltYm9sID09ICJOQ1IxIiwiZW5zZW1ibF9nZW5lX2lkIl0sICJsYWJlbCJdIDwtICJOQ1IxIgpkaWZmR2VuZVtkaWZmX2dlbmVzX0dfbGlzdFtkaWZmX2dlbmVzX0dfbGlzdCRoZ25jX3N5bWJvbCA9PSAiR1pNTSIsImVuc2VtYmxfZ2VuZV9pZCJdLCAibGFiZWwiXSA8LSAiR1pNTSIKCmxpYnJhcnkoZ2dyZXBlbCkKCmZpZzEwIDwtIGdncGxvdChkYXRhID0gZGlmZkdlbmUsIGFlcyh4ID0gbG9nMkZvbGRDaGFuZ2UsIHkgPSAtbG9nMTAocGFkaiksIGNvbG9yID0gc2lnbikpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMSkgKyAgI0NyZWF0ZSBzY2F0dGVyIHBsb3QKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygncmVkJywgJ2dyYXknLCAnZ3JlZW4nKSwgbGltaXRzID0gYygnVVAnLCAnbm9uZScsICdET1dOJykpICsgICNTZXQgdGhlIGNvbG9yCiAgbGFicyh4ID0gJ2xvZzIgRm9sZCBDaGFuZ2UnLCB5ID0gJy1sb2cxMCBhZGp1c3QgcC12YWx1ZScsIHRpdGxlID0gJ0hpZ2ggY2xvbmFsaXR5IHZzIExvdyBjbG9uYWxpdHknLCBjb2xvciA9ICcnKSArICAjU2V0IHRoZSBsYWJlbHMKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBzaXplID0gMTQpLCBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCAjQ2hhbmdlIHRoZSB0aGVtIGFuZCBncmlkIGxpbmVzCiAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICdibGFjaycsIGZpbGwgPSAndHJhbnNwYXJlbnQnKSwgCiAgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsID0gJ3RyYW5zcGFyZW50JykpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjKC0xLCAxKSwgbHR5ID0gMywgY29sb3IgPSAnYmxhY2snKSArICAjQWRkIHRocmVzaG9sZCBsaW5lCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMiwgbHR5ID0gMywgY29sb3IgPSAnYmxhY2snKSArCiAgeGxpbSgtMTIsIDEyKSArIHlsaW0oMCwgMzUpICsgI1NldCB0aGUgY3VydmUgYm91bmRhcnkKICBnZW9tX3RleHRfcmVwZWwoCiAgICBkYXRhID0gZGlmZkdlbmUsCiAgICBhZXMobGFiZWwgPSBsYWJlbCksCiAgICBzaXplID0gMywgc2VnbWVudC5jb2xvciA9ICJibHVlIiwgc2hvdy5sZWduZWQgPSBGQUxTRSwKICAgIHBvaW50LnBhZGRpbmcgPSB1bml0KDAuOCwgImxpbmVzIikKICApCgpmaWcxMApgYGAKCgojRmlndXJlMTEgUGhlbm90eXBlCgpgYGB7cn0KbGlicmFyeShIbWlzYykKCmxpYnJhcnkoY29ycnBsb3QpCgpsaWJyYXJ5KHJlYWR4bCkKCmJvbWkyX3BoZW5vIDwtIHJlYWRfZXhjZWwoIn4vUHJvamVjdC9CT01JMi9ib21pMl9waGVub3R5cGVkX2RlbnNpdGllcy54bHN4Iiwgc2hlZXQgPSAicGhlbm90eXBlZF9kZW5zaXRpZXMiKQoKVmlldyhib21pMl9waGVubykKCmJvbWkyX3BoZW5vIDwtIGFzLmRhdGEuZnJhbWUoYm9taTJfcGhlbm8sIHJvdy5uYW1lcyA9IGJvbWkyX3BoZW5vJElEKQoKcGhlbm9DbGluIDwtIG1lcmdlKEdpbmlDbGluX3R1bW9yLCBib21pMl9waGVubywgYnkgPSAiSUQiLCBzb3J0ID0gVFJVRSkKCnBoZW5vQ2xpbiA8LSBhcy5kYXRhLmZyYW1lKHBoZW5vQ2xpbiwgcm93Lm5hbWVzID0gcGhlbm9DbGluJElEKQoKd3JpdGUuY3N2KHBoZW5vQ2xpbiwgZmlsZSA9ICIvVXNlcnMvaHVpeXU4MTgvUHJvamVjdC9CT01JMi9ib21pMl9waGVub3R5cGVkX2RlbnNpdGllc19jbGluLmNzdiIpCgpwaGVub0NsaW5fZ2luaSA8LSBtZXJnZShHaW5pQ2xpbl90dW1vclssIGMoIklEIiwgIkdpbmlJbmRleCIsICJnaW5pR3JvdXAiKV0sIGJvbWkyX3BoZW5vLCBieT0iSUQiLCBzb3J0ID0gVFJVRSkKCnBoZW5vQ2xpbl9naW5pIDwtIGFzLmRhdGEuZnJhbWUocGhlbm9DbGluX2dpbmksIHJvdy5uYW1lcyA9IHBoZW5vQ2xpbl9naW5pJElEKQpwaGVub0NsaW5fZ2luaSRJRCA8LSBOVUxMCgpwaGVub0NsaW5fZ2luaTIgPC0gc3Vic2V0KHBoZW5vQ2xpbl9naW5pLCBzZWxlY3QgPSAtZ2luaUdyb3VwKQoKcGhlbm9DbGluX2dpbmkyIDwtIGFzLmRhdGEuZnJhbWUocGhlbm9DbGluX2dpbmkyKQoKcGhlbm9DbGluX2NvcnIgPC0gcmNvcnIoYXMubWF0cml4KHBoZW5vQ2xpbl9naW5pMiksIHR5cGUgPSAic3BlYXJtYW4iKQoKd3JpdGUuY3N2KHBoZW5vQ2xpbl9jb3JyJHIsIGZpbGUgPSAifi9Qcm9qZWN0L1RDUl9TdW1tYXJ5L0ZpZ3VyZTExL3BoZW5vQ29yLmNzdiIpCndyaXRlLmNzdihwaGVub0NsaW5fY29yciRQLCBmaWxlID0gIn4vUHJvamVjdC9UQ1JfU3VtbWFyeS9GaWd1cmUxMS9waGVub1B2YWx1ZS5jc3YiKQoKY29yKHBoZW5vQ2xpbl9naW5pMiwgdXNlID0gInBhaXJ3aXNlLmNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpCiMgcmVjb3JyIGFuZCBjb3IgZml0cyB3ZWxsCgpwaGVub0Nvcl9tZWx0IDwtIHJlYWRfZXhjZWwoIn4vUHJvamVjdC9UQ1JfU3VtbWFyeS9GaWd1cmUxMS9naW5pUGhlbm8ueGxzeCIsIHNoZWV0ID0gIm1lcmdlIikKCnBoZW5vQ29yX21lbHQgPC0gYXMuZGF0YS5mcmFtZShwaGVub0Nvcl9tZWx0KQoKcGhlbm9Db3JfbWVsdCR2YXIxIDwtIGZhY3RvcihwaGVub0Nvcl9tZWx0JHZhcjEsIGxldmVscyA9IGMoIkNENCBFZmYiLCJDRDQgVHJlZyIsIkNEOCBFZmYiLCJDRDggVHJlZyIsIkItY2VsbCIsIk5LLWNlbGwiLCJOS1QtY2VsbCIsIk0xIiwiTTIiLCJDRDE2MyIsImlEQyIsIm1EQyIsInBEQyIpKQoKcGhlbm9Db3JfbWVsdCR2YXIyIDwtIGZhY3RvcihwaGVub0Nvcl9tZWx0JHZhcjIsIGxldmVscyA9IGMoIlNBbmRUIiwiVHVtb3IiLCAiU3Ryb21hIikpCgpmaWcxMSA8LSBnZ3Bsb3QocGhlbm9Db3JfbWVsdCwgYWVzKHZhcjEsIHZhcjIsIGZpbGwgPSBDb3JyKSkgKwogIGdlb21fcG9pbnQoc2hhcGU9MjEsIGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAxMikrCiAgdGhlbWVfY2xhc3NpYygpKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGNvbG91cnMgPSByZXYoYnJld2VyLnBhbCg1LCAiU3BlY3RyYWwiKSkpKwogIGxhYnModGl0bGUgPSAiQ29ycmVsYXRpb24iLCB4ID0gIkNlbGwgcGhlbm90eXBlcyIsIHkgPSAiUG9zaXRpb24iKSArCiAgdGhlbWUoYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIiksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTUpKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbGFiZWwpLCBzaXplID0gNSwgY29sb3VyID0gImJsYWNrIikKCmZpZzExCmBgYAoKIyMgQ2x1c3RlcgojIyMgQWxsIGdpbmkKClRoaXMgbWV0aG9kIHN0YXJ0IGZyb20gdGhlIHQgY2VsbCBwaGVubyB0eXBlIGRhdGEgdG8gY2hlY2sgaWYgdGhlIGdpbmkgaW5kZXggaXMgbGlua2VkIHdpdGggdGhlc2UgZ3JvdXAuIEJ1dCB0aGVyZSBpcyBhbHNvIGEgYW5nbGUgdGhhdCBzdGFydCBmcm9tIEdpbmkgaW5kZXggKDI1JSkgdG8gYW5hbHl6ZSB0aGUgdCBjZWxsIGNvbXBvc2l0aW9uIGNoYW5nZXMKYGBge3J9CgojIGloY0hlYXRUX3R1bW9yX25vcm00IDwtIGloY0hlYXRULm5vcm0zW3Jvd25hbWVzKGloY0hlYXRUX3R1bW9yX25vcm0yKSxncmVwKCJTQW5kVE0iLCBjb2xuYW1lcyhpaGNIZWF0VC5ub3JtMykpXQojIAojIGloY0hlYXRUX3R1bW9yX25vcm00IDwtIG1lcmdlKEFCX0dpbmlfYW5ubywgaWhjSGVhdFRfdHVtb3Jfbm9ybTQsIGJ5PSJyb3cubmFtZXMiLCBhbGw9RkFMU0UpCiMgCiMgaWhjSGVhdFRfdHVtb3Jfbm9ybTQgPC0gYXMuZGF0YS5mcmFtZShpaGNIZWF0VF90dW1vcl9ub3JtNCwgcm93Lm5hbWVzID0gaWhjSGVhdFRfdHVtb3Jfbm9ybTQkUm93Lm5hbWVzKQojIGloY0hlYXRUX3R1bW9yX25vcm00JFJvdy5uYW1lcyA8LSBOVUxMCiMgCiMgaWhjSGVhdFRfdHVtb3Jfbm9ybTQgPC0gcmVuYW1lKGloY0hlYXRUX3R1bW9yX25vcm00LCBjKCJHaW5pSW5kZXgiPSJHaW5pIGluZGV4IikpCiMgCiMgaWhjSGVhdFRfdHVtb3Jfbm9ybTQgPC0gaWhjSGVhdFRfdHVtb3Jfbm9ybTQgJT4lIHJlbmFtZV93aXRoKH4gZ3N1YigiU1ExIiwgIl8iLC54KSkKIyAKIyBpaGNIZWF0VF90dW1vcl9ub3JtNCA8LSBpaGNIZWF0VF90dW1vcl9ub3JtNFssZ3JlcCgiQ0Q0NCIsIGNvbG5hbWVzKGloY0hlYXRUX3R1bW9yX25vcm00KSwgaW52ZXJ0ID0gVFJVRSldCgpwaGVub0NsaW5fZ2luaTMgPC0gcGhlbm9DbGluX2dpbmkyWywgZ3JlcCgiUGFuIiwgY29sbmFtZXMocGhlbm9DbGluX2dpbmkyKSwgaW52ZXJ0ID0gVCldCgpwaGVub0NsaW5fZ2luaTMubm9ybSA8LSBjYmluZChwaGVub0NsaW5fZ2luaTNbLDFdLHNjYWxlKHBoZW5vQ2xpbl9naW5pM1ssYygyOjQwKV0sIGNlbnRlciA9IFQsIHNjYWxlID0gVCkpCnBoZW5vQ2xpbl9naW5pMy5ub3JtIDwtIGFzLmRhdGEuZnJhbWUocGhlbm9DbGluX2dpbmkzLm5vcm0pCmNvbG5hbWVzKHBoZW5vQ2xpbl9naW5pMy5ub3JtKVtjb2xuYW1lcyhwaGVub0NsaW5fZ2luaTMubm9ybSkgPT0gIlYxIl0gPSAiR2luaUluZGV4IgpgYGAKCmBgYHtyfQptaW4ubWF4Lm5vcm0gPC0gZnVuY3Rpb24oeCl7CiAgKHggLSBtaW4oeCwgbmEucm0gPSBUUlVFKSkvKG1heCh4LCBuYS5ybSA9IFRSVUUpIC0gbWluKHgsIG5hLnJtID0gVFJVRSkpCn0KCnBoZW5vQ2xpbl9naW5pMy5ub3JtMiA8LSBhcHBseShwaGVub0NsaW5fZ2luaTNbLCBjKDI6NDApXSwgMiwgbWluLm1heC5ub3JtKQpwaGVub0NsaW5fZ2luaTMubm9ybTIgPC0gYXMuZGF0YS5mcmFtZShwaGVub0NsaW5fZ2luaTMubm9ybTIpCnBoZW5vQ2xpbl9naW5pMy5ub3JtMiA8LSBjYmluZChwaGVub0NsaW5fZ2luaTNbLDFdLCBwaGVub0NsaW5fZ2luaTMubm9ybTIpCmNvbG5hbWVzKHBoZW5vQ2xpbl9naW5pMy5ub3JtMilbY29sbmFtZXMocGhlbm9DbGluX2dpbmkzLm5vcm0yKSA9PSAicGhlbm9DbGluX2dpbmkzWywgMV0iXSA9ICJHaW5pSW5kZXgiCmBgYAoKCmBgYHtyfQpwaGVhdG1hcCh0KHBoZW5vQ2xpbl9naW5pMlssZ3JlcCgic3RfIiwgY29sbmFtZXMocGhlbm9DbGluX2dpbmkyKSwgaW52ZXJ0ID0gVCldKSwgY2x1c3RlcmluZ19tZXRob2QgPSAid2FyZC5EMiIsCiAgICAgICAgY2x1c3RlcmluZ19kaXN0YW5jZV9yb3dzID0gImV1Y2xpZGVhbiIsIGNsdXN0ZXJpbmdfZGlzdGFuY2VfY29scyA9ICJldWNsaWRlYW4iLAogICAgICAgIGN1dHJlZV9jb2xzID0gMiwKICAgICAgICAjY29sb3IgPSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwobiA9IDcsIG5hbWUgPSAiWWxHbkJ1IikpKDEwMCksCiAgICAgICAgYW5ub3RhdGlvbl9jb2wgPSBpaGNBbm5vLAogICAgICAgIGFubm90YXRpb25fY29sb3JzID0gaWhjQW5ub19jb2xvciwKICAgICAgICBmb250c2l6ZSA9IDUsCiAgICAgICAgc2hvd19jb2xuYW1lcyA9IEYpCgpwaGVhdG1hcCh0KHBoZW5vQ2xpbl9naW5pMy5ub3JtWyxjKDEsZ3JlcCgic3RfIiwgY29sbmFtZXMocGhlbm9DbGluX2dpbmkzLm5vcm1bLGMoMjoxNildKSwgaW52ZXJ0ID0gVCkrMSldKSwgY2x1c3RlcmluZ19tZXRob2QgPSAid2FyZC5EMiIsCiAgICAgICAgIGNsdXN0ZXJpbmdfZGlzdGFuY2Vfcm93cyA9ICJldWNsaWRlYW4iLCBjbHVzdGVyaW5nX2Rpc3RhbmNlX2NvbHMgPSAiZXVjbGlkZWFuIiwKICAgICAgICAgY3V0cmVlX2NvbHMgPSAyLAogICAgICAgICAjY29sb3IgPSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwobiA9IDcsIG5hbWUgPSAiWWxHbkJ1IikpKDEwMCksCiAgICAgICAgIGFubm90YXRpb25fY29sID0gaWhjQW5ubywKICAgICAgICAgYW5ub3RhdGlvbl9jb2xvcnMgPSBpaGNBbm5vX2NvbG9yLAogICAgICAgICBmb250c2l6ZSA9IDUsCiAgICAgICAgIHNob3dfY29sbmFtZXMgPSBGKQpwaGVhdG1hcCh0KHBoZW5vQ2xpbl9naW5pMy5ub3JtMlssZ3JlcCgic3RfIiwgY29sbmFtZXMocGhlbm9DbGluX2dpbmkzLm5vcm0yWyxjKDE6MTYpXSksIGludmVydCA9IFQpXSksIGNsdXN0ZXJpbmdfbWV0aG9kID0gIndhcmQuRDIiLAogICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX3Jvd3MgPSAiZXVjbGlkZWFuIiwgY2x1c3RlcmluZ19kaXN0YW5jZV9jb2xzID0gImV1Y2xpZGVhbiIsCiAgICAgICAgIGN1dHJlZV9jb2xzID0gMiwKICAgICAgICAgI2NvbG9yID0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKG4gPSA3LCBuYW1lID0gIllsR25CdSIpKSgxMDApLAogICAgICAgICBhbm5vdGF0aW9uX2NvbCA9IGloY0Fubm8sCiAgICAgICAgIGFubm90YXRpb25fY29sb3JzID0gaWhjQW5ub19jb2xvciwKICAgICAgICAgZm9udHNpemUgPSA1LAogICAgICAgICBzaG93X2NvbG5hbWVzID0gRikKCnBoZWF0bWFwKHQocGhlbm9DbGluX2dpbmkzLm5vcm0yWyxncmVwKCJzdF8iLCBjb2xuYW1lcyhwaGVub0NsaW5fZ2luaTMubm9ybTJbLGMoMjoxNildKSldKSwgY2x1c3RlcmluZ19tZXRob2QgPSAid2FyZC5EMiIsCiAgICAgICAgICBjbHVzdGVyX3Jvd3MgPSBGLCBjbHVzdGVyaW5nX2Rpc3RhbmNlX2NvbHMgPSAiZXVjbGlkZWFuIiwKICAgICAgICAgIGN1dHJlZV9jb2xzID0gNSwKICAgICAgICAgICNjb2xvciA9IGNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbChuID0gOSwgbmFtZSA9ICJZbE9yQnIiKSkoMTAwKSwKICAgICAgICAgIGFubm90YXRpb25fY29sID0gaWhjQW5ubywKICAgICAgICAgIGFubm90YXRpb25fY29sb3JzID0gaWhjQW5ub19jb2xvciwKICAgICAgICAgIGZvbnRzaXplID0gNSwKICAgICAgICAgIHNob3dfY29sbmFtZXMgPSBGKQpgYGAKCmBgYHtyfQpmaWcxMWIgPC0gcGhlYXRtYXAodChwaGVub0NsaW5fZ2luaTMubm9ybTJbLGMoMSxncmVwKCJzdF8iLCBjb2xuYW1lcyhwaGVub0NsaW5fZ2luaTMubm9ybTJbLGMoMjoxNildKSkrMSldKSwgY2x1c3RlcmluZ19tZXRob2QgPSAid2FyZC5EMiIsCiAgICAgICAgICBjbHVzdGVyX3Jvd3MgPSBGLCBjbHVzdGVyaW5nX2Rpc3RhbmNlX2NvbHMgPSAiZXVjbGlkZWFuIiwKICAgICAgICAgIGN1dHJlZV9jb2xzID0gMywKICAgICAgICAgICNjb2xvciA9IGNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbChuID0gOSwgbmFtZSA9ICJZbE9yQnIiKSkoMTAwKSwKICAgICAgICAgIGFubm90YXRpb25fY29sID0gaWhjQW5ubywKICAgICAgICAgIGFubm90YXRpb25fY29sb3JzID0gaWhjQW5ub19jb2xvciwKICAgICAgICAgIGZvbnRzaXplID0gNSwKICAgICAgICAgIHNob3dfY29sbmFtZXMgPSBGKQpmaWcxMWIKIyBwaGVhdG1hcCh0KHBoZW5vQ2xpbl9naW5pMy5ub3JtMlssYygxLGdyZXAoInN0XyIsIGNvbG5hbWVzKHBoZW5vQ2xpbl9naW5pMy5ub3JtMlssYygyOjE2KV0pKSsxKV0pLCBjbHVzdGVyaW5nX21ldGhvZCA9ICJ3YXJkLkQyIiwKIyAgICAgICAgICBjbHVzdGVyX3Jvd3MgPSBGLCBjbHVzdGVyaW5nX2Rpc3RhbmNlX2NvbHMgPSAiZXVjbGlkZWFuIiwKIyAgICAgICAgICBjdXRyZWVfY29scyA9IDYsCiMgICAgICAgICAgI2NvbG9yID0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKG4gPSA5LCBuYW1lID0gIllsT3JCciIpKSgxMDApLAojICAgICAgICAgIGFubm90YXRpb25fY29sID0gaWhjQW5ubywKIyAgICAgICAgICBhbm5vdGF0aW9uX2NvbG9ycyA9IGloY0Fubm9fY29sb3IsCiMgICAgICAgICAgZm9udHNpemUgPSAxMCwKIyAgICAgICAgICBzaG93X2NvbG5hbWVzID0gRikKYGBgCgpgYGB7cn0KcGhlYXRtYXAodChwaGVub0NsaW5fZ2luaTMubm9ybTJbLGdyZXAoInN0XyIsIGNvbG5hbWVzKHBoZW5vQ2xpbl9naW5pMy5ub3JtMlssYygyOjEzKV0pKSsxXSksIGNsdXN0ZXJpbmdfbWV0aG9kID0gIndhcmQuRDIiLAogICAgICAgICBjbHVzdGVyX3Jvd3MgPSBGLCBjbHVzdGVyaW5nX2Rpc3RhbmNlX2NvbHMgPSAiZXVjbGlkZWFuIiwKICAgICAgICAgY3V0cmVlX2NvbHMgPSA0LAogICAgICAgICAjY29sb3IgPSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwobiA9IDksIG5hbWUgPSAiWWxPckJyIikpKDEwMCksCiAgICAgICAgIGFubm90YXRpb25fY29sID0gaWhjQW5ubywKICAgICAgICAgYW5ub3RhdGlvbl9jb2xvcnMgPSBpaGNBbm5vX2NvbG9yLAogICAgICAgICBmb250c2l6ZSA9IDEwLAogICAgICAgICBzaG93X2NvbG5hbWVzID0gRikKYGBgCgoKYGBge3J9CmZpZzExYi5jbHVzdGVyIDwtIGZpZzExYiR0cmVlX2NvbAoKZmlnMTFiLmNsdXN0ZXIucGxvdCA8LSBwbG90KGZpZzExYi5jbHVzdGVyLCBoYW5nID0gLTEsIGNleD0wLjYsIGF4ZXM9RkFMU0UsIGFubj1GQUxTRSkKCmZpZzExYi5jdXQgPC0gY3V0cmVlKGZpZzVkX1QuY2x1c3RlciwgMykKCiMgZmlnNWRfVC5jdXRfMSA8LSBuYW1lcyhmaWc1ZF9ULmN1dClbZmlnNWRfVC5jdXQgPT0gMV0KIyBmaWc1ZF9ULmN1dF8yIDwtIG5hbWVzKGZpZzVkX1QuY3V0KVtmaWc1ZF9ULmN1dCA9PSAyXQojIAojIGZpZzVkX1QuY3V0X2dpbmkgPC0gbWVyZ2UoQUJfR2luaV9hbm5vLCBmaWc1ZF9ULmN1dCwgYnkgPSAicm93Lm5hbWVzIiwgYWxsLnkgPSBUUlVFKQojIAojIGZpZzVkX1QuY3V0X2dpbmkgPC0gYXMuZGF0YS5mcmFtZShmaWc1ZF9ULmN1dF9naW5pLCByb3cubmFtZXMgPSBmaWc1ZF9ULmN1dF9naW5pJFJvdy5uYW1lcykKIyAKIyBmaWc1ZF9ULmN1dF9naW5pJFJvdy5uYW1lcyA8LSBOVUxMCiMgCiMgZmlnNWRfVC5jdXRfZ2luaSA8LSByZW5hbWUoZmlnNWRfVC5jdXRfZ2luaSwgYygiQ2x1c3RlciI9InkiKSkKYGBgCgpgYGB7cn0KZmlnMTFjIDwtIHBoZWF0bWFwKHQocGhlbm9DbGluX2dpbmkzLm5vcm0yWyEocm93bmFtZXMocGhlbm9DbGluX2dpbmkzLm5vcm0yKSA9PSAiTDQ2NFQiKSxncmVwKCJzdF8iLCBjb2xuYW1lcyhwaGVub0NsaW5fZ2luaTMubm9ybTJbLGMoMToxNCldKSldKSwKICAgICAgICAgICAgICAgICAgIGNsdXN0ZXJpbmdfbWV0aG9kID0gIndhcmQuRDIiLAogICAgICAgICAgICAgICAgICAgY2x1c3Rlcl9yb3dzID0gRiwgY2x1c3RlcmluZ19kaXN0YW5jZV9jb2xzID0gImV1Y2xpZGVhbiIsCiAgICAgICAgICAgICAgICAgICBjdXRyZWVfY29scyA9IDQsCiAgICAgICAgICAgICAgICAgICAjY29sb3IgPSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwobiA9IDksIG5hbWUgPSAiWWxPckJyIikpKDEwMCksCiAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uX2NvbCA9IGloY0Fubm8sCiAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uX2NvbG9ycyA9IGloY0Fubm9fY29sb3IsCiAgICAgICAgICAgICAgICAgICBmb250c2l6ZSA9IDUsCiAgICAgICAgICAgICAgICAgICBzaG93X2NvbG5hbWVzID0gRikKYGBgCgpgYGB7cn0KZmlnMTFjLmNsdXN0ZXIgPC0gZmlnMTFjJHRyZWVfY29sCgpmaWcxMWMuY2x1c3Rlci5wbG90IDwtIHBsb3QoZmlnMTFjLmNsdXN0ZXIsIGhhbmcgPSAtMSwgY2V4PTAuNiwgYXhlcz1GQUxTRSwgYW5uPUZBTFNFKQoKZmlnMTFjLmN1dCA8LSBjdXRyZWUoZmlnMTFjLmNsdXN0ZXIsIDQpCmBgYAoKYGBge3J9CmZpZzExYy5jdXRfZ2luaSA8LSBtZXJnZShwaGVub0NsaW5fZ2luaTMubm9ybTJbIShyb3duYW1lcyhwaGVub0NsaW5fZ2luaTMubm9ybTIpID09ICJMNDY0VCIpLGMoMSxncmVwKCJzdF8iLCBjb2xuYW1lcyhwaGVub0NsaW5fZ2luaTMubm9ybTJbLGMoMToxNCldKSkpXSwKICAgICAgICAgICAgICAgICAgICAgICAgIGZpZzExYy5jdXQsIGJ5ID0gInJvdy5uYW1lcyIsIGFsbC55ID0gVFJVRSkKZmlnMTFjLmN1dF9naW5pIDwtIGFzLmRhdGEuZnJhbWUoZmlnMTFjLmN1dF9naW5pLCByb3cubmFtZXMgPSBmaWcxMWMuY3V0X2dpbmkkUm93Lm5hbWVzKQpmaWcxMWMuY3V0X2dpbmkkUm93Lm5hbWVzIDwtIE5VTEwKY29sbmFtZXMoZmlnMTFjLmN1dF9naW5pKVtjb2xuYW1lcyhmaWcxMWMuY3V0X2dpbmkpID09ICJ5Il0gPC0gIkN1dEdyb3VwIgpmaWcxMWMuY3V0X2dpbmkkQ3V0R3JvdXAgPSBmYWN0b3IoZmlnMTFjLmN1dF9naW5pJEN1dEdyb3VwKQpgYGAKCmBgYHtyfQpnZ3Bsb3QoZmlnMTFjLmN1dF9naW5pLCBhZXMoeCA9IEN1dEdyb3VwLCB5ID0gR2luaUluZGV4LCBmaWxsPUN1dEdyb3VwKSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLmNvbG91ciA9ICJibGFjayIsIG91dGxpZXIuc2hhcGUgPSAxNiwgb3V0bGllci5zaXplID0gMiwgY29sb3VyID0gImJsYWNrIiwgbm90Y2ggPSBGQUxTRSkgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgI2Nvb3JkX2ZsaXAoKSArCiAgI3NjYWxlX2NvbG9yX25wZygpICsKICBsYWJzKHRpdGxlID0gIkdpbmkiLCB4ID0gIkdyb3VwIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gTlVMTCkKYGBgCmBgYHtyfQpnZ3Bsb3QoZmlnMTFjLmN1dF9naW5pLCBhZXMoeCA9IEN1dEdyb3VwLCB5ID0gc19DRDRfVHJlZywgZmlsbD1DdXRHcm91cCkpICsKICBnZW9tX2JveHBsb3Qob3V0bGllci5jb2xvdXIgPSAiYmxhY2siLCBvdXRsaWVyLnNoYXBlID0gMTYsIG91dGxpZXIuc2l6ZSA9IDIsIGNvbG91ciA9ICJibGFjayIsIG5vdGNoID0gRkFMU0UpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogICNjb29yZF9mbGlwKCkgKwogICNzY2FsZV9jb2xvcl9ucGcoKSArCiAgbGFicyh0aXRsZSA9ICJDRDRfVHJlZyIsIHggPSAiR3JvdXAiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBOVUxMKQpgYGAKYGBge3J9CmdncGxvdChmaWcxMWMuY3V0X2dpbmksIGFlcyh4ID0gQ3V0R3JvdXAsIHkgPSBzdF9DRDRfRWZmLCBmaWxsPUN1dEdyb3VwKSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLmNvbG91ciA9ICJibGFjayIsIG91dGxpZXIuc2hhcGUgPSAxNiwgb3V0bGllci5zaXplID0gMiwgY29sb3VyID0gImJsYWNrIiwgbm90Y2ggPSBGQUxTRSkgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgI2Nvb3JkX2ZsaXAoKSArCiAgI3NjYWxlX2NvbG9yX25wZygpICsKICBsYWJzKHRpdGxlID0gIkNENF9FZmYiLCB4ID0gIkdyb3VwIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gTlVMTCkKYGBgCgpgYGB7cn0KZmlnMTFjLmN1dF9naW5pLm1lbHQgPC0gbWVsdChmaWcxMWMuY3V0X2dpbmksIG5hLnJtID0gRikKCmdncGxvdChmaWcxMWMuY3V0X2dpbmkubWVsdCwgYWVzKHggPSB2YXJpYWJsZSwgeSA9IHZhbHVlLCBmaWxsPUN1dEdyb3VwKSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLmNvbG91ciA9ICJibGFjayIsIG91dGxpZXIuc2hhcGUgPSAxNiwgb3V0bGllci5zaXplID0gMiwgY29sb3VyID0gImJsYWNrIiwgbm90Y2ggPSBGQUxTRSkgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgI2Nvb3JkX2ZsaXAoKSArCiAgc2NhbGVfZmlsbF9ucGcocGFsZXR0ZSA9IGMoIm5yYyIpLCBhbHBoYT0xKSArCiAgbGFicyh4ID0gIlQgY2VsbCBwaGVub3R5cGUiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIiksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MjApKQogICNzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gTlVMTCkKYGBgCmBgYHtyfQpnZ3Bsb3QoZmlnMTFjLmN1dF9naW5pLm1lbHQsIGFlcyh4ID0gdmFyaWFibGUsIHkgPSB2YWx1ZSwgZmlsbD12YXJpYWJsZSkpICsKICBnZW9tX2JveHBsb3Qob3V0bGllci5jb2xvdXIgPSAiYmxhY2siLCBvdXRsaWVyLnNoYXBlID0gMTYsIG91dGxpZXIuc2l6ZSA9IDIsIGNvbG91ciA9ICJibGFjayIsIG5vdGNoID0gRkFMU0UpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogICNjb29yZF9mbGlwKCkgKwogIHNjYWxlX2ZpbGxfbnBnKHBhbGV0dGUgPSBjKCJucmMiKSwgYWxwaGE9MSkgKwogIGxhYnMoeCA9ICJUIGNlbGwgcGhlbm90eXBlIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkgKwogIGZhY2V0X3dyYXAofkN1dEdyb3VwLG5jb2wgPSAxKQpgYGAKCiMjIyBTbW9vdGggbGluZQpgYGB7cn0KZmlnMTFjLmN1dF9naW5pLm1lbHQyIDwtIG1lbHQoY2JpbmQoIklEIj1yb3duYW1lcyhmaWcxMWMuY3V0X2dpbmkpLGZpZzExYy5jdXRfZ2luaVssYygxOjUpXSksIG5hLnJtID0gRiwgaWQudmFycyA9IGMoIklEIiwgIkdpbmlJbmRleCIpLCB2YXJpYWJsZS5mYWN0b3IgPUYpCgpmaWcxMWMuY3V0X2dpbmkubWVsdDIkdmFyaWFibGUgPC0gYXMuZmFjdG9yKGZpZzExYy5jdXRfZ2luaS5tZWx0MiR2YXJpYWJsZSkKCiMgU21vb3RoIHZhbHVlIHRyZW5kIGxpbmUKZ2dwbG90KGZpZzExYy5jdXRfZ2luaS5tZWx0MiwgYWVzKHggPSBHaW5pSW5kZXgsIHkgPSB2YWx1ZSkpICsKICBnZW9tX3Ntb290aChhZXMoY29sb3I9dmFyaWFibGUsZmlsbD12YXJpYWJsZSksIG1ldGhvZCA9ICJsb2VzcyIpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogICNjb29yZF9mbGlwKCkgKwogIHNjYWxlX2NvbG9yX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTEpICsKICBzY2FsZV9maWxsX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTEpICsKICBsYWJzKHggPSAiR2luaSBjb2VmZmljaWVudCIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpCgojIFJhdyBzdGFja2luZyB2YWx1ZQpnZ3Bsb3QoZmlnMTFjLmN1dF9naW5pLm1lbHQyLCBhZXMoeCA9IEdpbmlJbmRleCwgeSA9IHZhbHVlLGZpbGw9dmFyaWFibGUpKSArCiAgZ2VvbV9hcmVhKCkgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgI2Nvb3JkX2ZsaXAoKSArCiAgc2NhbGVfY29sb3JfbnBnKHBhbGV0dGUgPSBjKCJucmMiKSwgYWxwaGE9MSkgKwogIHNjYWxlX2ZpbGxfbnBnKHBhbGV0dGUgPSBjKCJucmMiKSwgYWxwaGE9MSkgKwogIGxhYnMoeCA9ICJHaW5pIGNvZWZmaWNpZW50IikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkKCiMgUmF3IGZyYWN0aW9uIGNoYW5nZQpnZ3Bsb3QoZmlnMTFjLmN1dF9naW5pLm1lbHQyLCBhZXMoeCA9IEdpbmlJbmRleCwgeSA9IHZhbHVlLGZpbGw9dmFyaWFibGUpKSArCiAgICBnZW9tX2FyZWEocG9zaXRpb24gPSAiZmlsbCIpICsKICAgIHRoZW1lX2NsYXNzaWMoKSArCiAgICAjY29vcmRfZmxpcCgpICsKICAgIHNjYWxlX2NvbG9yX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTAuOCkgKwogICAgc2NhbGVfZmlsbF9ucGcocGFsZXR0ZSA9IGMoIm5yYyIpLCBhbHBoYT0wLjgpICsKICAgIGxhYnMoeCA9ICJHaW5pIGNvZWZmaWNpZW50IikgKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIiksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MjApKQoKIyBzbW9vdGggZGVuc2l0eSB2YWx1ZQpnZ3Bsb3QoZmlnMTFjLmN1dF9naW5pLm1lbHQyLCBhZXMoeCA9IEdpbmlJbmRleCwgeSA9IHZhbHVlLGZpbGw9dmFyaWFibGUpKSArCiAgZ2VvbV9hcmVhKGZpbGw9TkEpICsKICBzdGF0X3Ntb290aChnZW9tID0gImFyZWEiLCBtZXRob2QgPSAibG9lc3MiLCBzcGFuID0gMS8zLCBhbHBoYT0wLjQpKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgI2Nvb3JkX2ZsaXAoKSArCiAgc2NhbGVfY29sb3JfbnBnKHBhbGV0dGUgPSBjKCJucmMiKSwgYWxwaGE9MSkgKwogIHNjYWxlX2ZpbGxfbnBnKHBhbGV0dGUgPSBjKCJucmMiKSwgYWxwaGE9MSkgKwogIGxhYnMoeCA9ICJHaW5pIGNvZWZmaWNpZW50IikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkKCiMgU21vb3RoIHN0YWNraW5nIGRlbnNpdHkgdmFsdWUKZ2dwbG90KGZpZzExYy5jdXRfZ2luaS5tZWx0MiwgYWVzKHggPSBHaW5pSW5kZXgsIHkgPSB2YWx1ZSkpICsKICAgIHN0YXRfc21vb3RoKGFlcyhjb2xvcj12YXJpYWJsZSxmaWxsPXZhcmlhYmxlKSwgbWV0aG9kID0gImxvZXNzIiwgZ2VvbT0iYXJlYSIsIHBvc2l0aW9uID0gInN0YWNrIixzcGFuID0gMC41KSArCiAgICB0aGVtZV9jbGFzc2ljKCkgKwogICAgI2Nvb3JkX2ZsaXAoKSArCiAgICBzY2FsZV9jb2xvcl9ucGcocGFsZXR0ZSA9IGMoIm5yYyIpLCBhbHBoYT0xKSArCiAgICBzY2FsZV9maWxsX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTAuNykgKwogICAgbGFicyh4ID0gIkdpbmkgY29lZmZpY2llbnQiKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpCgojIFNtb290aCBmcmFjdGlvbiBjaGFuZ2VzCmdncGxvdChmaWcxMWMuY3V0X2dpbmkubWVsdDIsIGFlcyh4ID0gR2luaUluZGV4LCB5ID0gdmFsdWUpKSArCiAgICBzdGF0X3Ntb290aChhZXMoY29sb3I9dmFyaWFibGUsZmlsbD12YXJpYWJsZSksIG1ldGhvZCA9ICJsb2VzcyIsIGdlb209ImFyZWEiLCBwb3NpdGlvbiA9ICJmaWxsIixzcGFuID0gMC4zKSArCiAgICB0aGVtZV9jbGFzc2ljKCkgKwogICAgI2Nvb3JkX2ZsaXAoKSArCiAgICBzY2FsZV9jb2xvcl9ucGcocGFsZXR0ZSA9IGMoIm5yYyIpLCBhbHBoYT0xKSArCiAgICBzY2FsZV9maWxsX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTAuNykgKwogICAgbGFicyh4ID0gIkdpbmkgY29lZmZpY2llbnQiKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpKwogICAgc2NhbGVfeF9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSwgbGltaXRzID0gYygwLDAuOCkpICsgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSwgbGltaXRzID0gYygwLDEpKQoKCiMgUmF3IGZyYWN0aW9uIGNoYW5nZSBvZiB1bm5vcm1hbGl6ZWQgZGF0YQpwaGVub0NsaW5fZ2luaTMubWVsdCA8LSBtZWx0KGNiaW5kKCJJRCI9cm93bmFtZXMocGhlbm9DbGluX2dpbmkzKSxwaGVub0NsaW5fZ2luaTNbLGMoMSxncmVwKCJzdF8iLCBjb2xuYW1lcyhwaGVub0NsaW5fZ2luaTNbLGMoMToxMyldKSkpXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm0gPSBGLCBpZC52YXJzID0gYygiSUQiLCAiR2luaUluZGV4IiksIHZhcmlhYmxlLmZhY3RvciA9RikKCmdncGxvdChwaGVub0NsaW5fZ2luaTMubWVsdCwgYWVzKHggPSBHaW5pSW5kZXgsIHkgPSB2YWx1ZSxmaWxsPXZhcmlhYmxlKSkgKwogICAgZ2VvbV9hcmVhKHBvc2l0aW9uID0gImZpbGwiKSArCiAgICB0aGVtZV9jbGFzc2ljKCkgKwogICAgI2Nvb3JkX2ZsaXAoKSArCiAgICBzY2FsZV9jb2xvcl9ucGcocGFsZXR0ZSA9IGMoIm5yYyIpLCBhbHBoYT0wLjgpICsKICAgIHNjYWxlX2ZpbGxfbnBnKHBhbGV0dGUgPSBjKCJucmMiKSwgYWxwaGE9MC44KSArCiAgICBsYWJzKHggPSAiR2luaSBjb2VmZmljaWVudCIpICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkKCiMgUmF3IHN0YWNraW5nIG9mIHVubm9ybWFsaXplZCBkYXRhCmdncGxvdChwaGVub0NsaW5fZ2luaTMubWVsdCwgYWVzKHggPSBHaW5pSW5kZXgsIHkgPSB2YWx1ZSxmaWxsPXZhcmlhYmxlKSkgKwogICAgZ2VvbV9hcmVhKHBvc2l0aW9uID0gInN0YWNrIikgKwogICAgdGhlbWVfY2xhc3NpYygpICsKICAgICNjb29yZF9mbGlwKCkgKwogICAgc2NhbGVfY29sb3JfbnBnKHBhbGV0dGUgPSBjKCJucmMiKSwgYWxwaGE9MC44KSArCiAgICBzY2FsZV9maWxsX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTAuOCkgKwogICAgbGFicyh4ID0gIkdpbmkgY29lZmZpY2llbnQiKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpCgojIFNtb290aCBmcmFjdGlvbiBjaGFuZ2Ugb2YgdW5ub3JtYWxpemVkIGRhdGEKZ2dwbG90KHBoZW5vQ2xpbl9naW5pMy5tZWx0LCBhZXMoeCA9IEdpbmlJbmRleCwgeSA9IHZhbHVlKSkgKwogICAgc3RhdF9zbW9vdGgoYWVzKGNvbG9yPXZhcmlhYmxlLGZpbGw9dmFyaWFibGUpLCBtZXRob2QgPSAibG9lc3MiLCBnZW9tPSJhcmVhIiwgcG9zaXRpb24gPSAiZmlsbCIsc3BhbiA9IDAuMykgKwogICAgdGhlbWVfY2xhc3NpYygpICsKICAgICNjb29yZF9mbGlwKCkgKwogICAgc2NhbGVfY29sb3JfbnBnKHBhbGV0dGUgPSBjKCJucmMiKSwgYWxwaGE9MSkgKwogICAgc2NhbGVfZmlsbF9ucGcocGFsZXR0ZSA9IGMoIm5yYyIpLCBhbHBoYT0wLjcpICsKICAgIGxhYnMoeCA9ICJHaW5pIGNvZWZmaWNpZW50IikgKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIiksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MjApKSsKICAgIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsMCksIGxpbWl0cyA9IGMoMCwxKSkKCiMgU21vb3RoIHN0YWNraW5nIHVubm9ybWFsaXplZCBkYXRhCmdncGxvdChwaGVub0NsaW5fZ2luaTMubWVsdCwgYWVzKHggPSBHaW5pSW5kZXgsIHkgPSB2YWx1ZSkpICsKICAgIHN0YXRfc21vb3RoKGFlcyhjb2xvcj12YXJpYWJsZSxmaWxsPXZhcmlhYmxlKSwgbWV0aG9kID0gImxvZXNzIiwgZ2VvbT0iYXJlYSIsIHBvc2l0aW9uID0gInN0YWNrIixzcGFuID0gMC4zKSArCiAgICB0aGVtZV9jbGFzc2ljKCkgKwogICAgI2Nvb3JkX2ZsaXAoKSArCiAgICBzY2FsZV9jb2xvcl9ucGcocGFsZXR0ZSA9IGMoIm5yYyIpLCBhbHBoYT0xKSArCiAgICBzY2FsZV9maWxsX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTAuNykgKwogICAgbGFicyh4ID0gIkdpbmkgY29lZmZpY2llbnQiKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpCgpgYGAKCmBgYHtyfQojIFJhdyBzdGFja2luZyBwbG90IHdpdGggc2FtcHBsZSBkZW5zaXR5IHVzaW5nIApmaWcxMV9naW5pIDwtIGdncGxvdChmaWcxMWMuY3V0X2dpbmkubWVsdDIsIGFlcyh4ID0gR2luaUluZGV4LCB5ID0gMSkpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PWZpZzExYy5jdXRfZ2luaS5tZWx0MltmaWcxMWMuY3V0X2dpbmkubWVsdDIkdmFyaWFibGUgPT0gInN0X0NENF9FZmYiLCAiR2luaUluZGV4Il0pICsgdGhlbWVfY2xhc3NpYygpICsgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSkKCiMgbm9ybWFsaXplZCByYXcgc3RhY2tpbmcgZGF0YQpmaWcxMWVfbm9ybVMgPC0gZ2dwbG90KGZpZzExYy5jdXRfZ2luaS5tZWx0MiwgYWVzKHggPSBHaW5pSW5kZXgsIHkgPSB2YWx1ZSxmaWxsPXZhcmlhYmxlKSkgKwogIGdlb21fYXJlYSgpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogICNjb29yZF9mbGlwKCkgKwogIHNjYWxlX2NvbG9yX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTEpICsKICBzY2FsZV9maWxsX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTEpICsKICBsYWJzKHggPSAiR2luaSBjb2VmZmljaWVudCIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpCgojIHJhdyBzdGFja2luZyBkYXRhCmZpZzExZV9yYXdTIDwtIGdncGxvdChwaGVub0NsaW5fZ2luaTMubWVsdCwgYWVzKHggPSBHaW5pSW5kZXgsIHkgPSB2YWx1ZSxmaWxsPXZhcmlhYmxlKSkgKwogIGdlb21fYXJlYSgpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogICNjb29yZF9mbGlwKCkgKwogIHNjYWxlX2NvbG9yX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTEpICsKICBzY2FsZV9maWxsX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTEpICsKICBsYWJzKHggPSAiR2luaSBjb2VmZmljaWVudCIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpCgojIHNtb290aGVkIHJhdyBzdGFja2luZyBkYXRhCmZpZzExZV9yYXdTdGFja1Ntb290aCA8LSBnZ3Bsb3QocGhlbm9DbGluX2dpbmkzLm1lbHQsIGFlcyh4ID0gR2luaUluZGV4LCB5ID0gdmFsdWUpKSArCiAgICBzdGF0X3Ntb290aChhZXMoY29sb3I9dmFyaWFibGUsZmlsbD12YXJpYWJsZSksIG1ldGhvZCA9ICJsb2VzcyIsIGdlb209ImFyZWEiLCBwb3NpdGlvbiA9ICJzdGFjayIsc3BhbiA9IDAuNCkgKwogICAgdGhlbWVfY2xhc3NpYygpICsKICAgICNjb29yZF9mbGlwKCkgKwogICAgc2NhbGVfY29sb3JfbnBnKHBhbGV0dGUgPSBjKCJucmMiKSwgYWxwaGE9MSkgKwogICAgc2NhbGVfZmlsbF9ucGcocGFsZXR0ZSA9IGMoIm5yYyIpLCBhbHBoYT0wLjkpICsKICAgIGxhYnMoeCA9ICJHaW5pIGNvZWZmaWNpZW50IikgKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIiksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MjApKQoKIyBzbW9vdGhlZCByYXcgZnJhY3Rpb24gY2hhbmdlIGRhdGEKZmlnMTFlX3Jhd1Ntb290aCA8LSBnZ3Bsb3QocGhlbm9DbGluX2dpbmkzLm1lbHQsIGFlcyh4ID0gR2luaUluZGV4LCB5ID0gdmFsdWUpKSArCiAgICBzdGF0X3Ntb290aChhZXMoY29sb3I9dmFyaWFibGUsZmlsbD12YXJpYWJsZSksIG1ldGhvZCA9ICJsb2VzcyIsIGdlb209ImFyZWEiLCBwb3NpdGlvbiA9ICJmaWxsIixzcGFuID0gMC40KSArCiAgICB0aGVtZV9jbGFzc2ljKCkgKwogICAgI2Nvb3JkX2ZsaXAoKSArCiAgICBzY2FsZV9jb2xvcl9ucGcocGFsZXR0ZSA9IGMoIm5yYyIpLCBhbHBoYT0xKSArCiAgICBzY2FsZV9maWxsX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTAuOSkgKwogICAgbGFicyh4ID0gIkdpbmkgY29lZmZpY2llbnQiKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpCgpnZ2FycmFuZ2UoZmlnMTFlX3Jhd1MsIGZpZzExX2dpbmksIG5jb2wgPSAxLCBucm93ID0gMiwgYWxpZ24gPSAiaHYiKQoKZ2dhcnJhbmdlKGZpZzExZV9yYXdTbW9vdGgsIGZpZzExX2dpbmksIG5jb2wgPSAxLCBucm93ID0gMiwgYWxpZ24gPSAiaHYiKQoKZ2dhcnJhbmdlKGZpZzExZV9yYXdTdGFja1Ntb290aCwgZmlnMTFlX3Jhd1Ntb290aCwgZmlnMTFfZ2luaSwgbmNvbCA9IDEsIG5yb3cgPSAzLCBhbGlnbiA9ICJodiIsIGNvbW1vbi5sZWdlbmQgPSBUKQoKYGBgCgoKIyMjIE9yZGVyZWQgYnkgZ2luaQpgYGB7cn0KcGhlYXRtYXAodChwaGVub0NsaW5fZ2luaTMubm9ybTJbb3JkZXIocGhlbm9DbGluX2dpbmkzLm5vcm0yJEdpbmlJbmRleCksYygyOjQwKV0pLAogICAgICAgICBjbHVzdGVyaW5nX21ldGhvZCA9ICJ3YXJkLkQyIiwKICAgICAgICAgY2x1c3Rlcl9yb3dzID0gRiwgY2x1c3RlcmluZ19kaXN0YW5jZV9jb2xzID0gImV1Y2xpZGVhbiIsCiAgICAgICAgIGN1dHJlZV9jb2xzID0gNCwKICAgICAgICAgI2NvbG9yID0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKG4gPSA5LCBuYW1lID0gIllsT3JCciIpKSgxMDApLAogICAgICAgICBhbm5vdGF0aW9uX2NvbCA9IGloY0Fubm8sCiAgICAgICAgIGFubm90YXRpb25fY29sb3JzID0gaWhjQW5ub19jb2xvciwKICAgICAgICAgZm9udHNpemUgPSA1LAogICAgICAgICBzaG93X2NvbG5hbWVzID0gRikKCnBoZWF0bWFwKHQocGhlbm9DbGluX2dpbmkzLm5vcm0yW29yZGVyKHBoZW5vQ2xpbl9naW5pMy5ub3JtMiRHaW5pSW5kZXgpLGMoMTc6MzEpXSksCiAgICAgICAgIGNsdXN0ZXJpbmdfbWV0aG9kID0gIndhcmQuRDIiLAogICAgICAgICBjbHVzdGVyX3Jvd3MgPSBGLCBjbHVzdGVyX2NvbHMgPSBGLAogICAgICAgICBjdXRyZWVfY29scyA9IDQsCiAgICAgICAgICNjb2xvciA9IGNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbChuID0gOSwgbmFtZSA9ICJZbE9yQnIiKSkoMTAwKSwKICAgICAgICAgYW5ub3RhdGlvbl9jb2wgPSBpaGNBbm5vLAogICAgICAgICBhbm5vdGF0aW9uX2NvbG9ycyA9IGloY0Fubm9fY29sb3IsCiAgICAgICAgIGZvbnRzaXplID0gNSwKICAgICAgICAgc2hvd19jb2xuYW1lcyA9IEYpCmBgYAoKIyMjIEhpZ2ggZ2luaSBncm91cApgYGB7cn0KZmlnMTFkIDwtIHBoZWF0bWFwKHQocGhlbm9DbGluX2dpbmkzLm5vcm0yW3BoZW5vQ2xpbl9naW5pMy5ub3JtMiRHaW5pSW5kZXggPj0gMC4yNTQzMSxncmVwKCJzdF8iLCBjb2xuYW1lcyhwaGVub0NsaW5fZ2luaTMubm9ybTJbLGMoMToxNCldKSldKSwKICAgICAgICAgICAgICAgICAgIGNsdXN0ZXJpbmdfbWV0aG9kID0gIndhcmQuRDIiLAogICAgICAgICAgICAgICAgICAgY2x1c3Rlcl9yb3dzID0gRiwgY2x1c3RlcmluZ19kaXN0YW5jZV9jb2xzID0gImV1Y2xpZGVhbiIsCiAgICAgICAgICAgICAgICAgICBjdXRyZWVfY29scyA9IDMsCiAgICAgICAgICAgICAgICAgICAjY29sb3IgPSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwobiA9IDksIG5hbWUgPSAiWWxPckJyIikpKDEwMCksCiAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uX2NvbCA9IGloY0Fubm8sCiAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uX2NvbG9ycyA9IGloY0Fubm9fY29sb3IsCiAgICAgICAgICAgICAgICAgICBmb250c2l6ZSA9IDUsCiAgICAgICAgICAgICAgICAgICBzaG93X2NvbG5hbWVzID0gRikKCmBgYAoKYGBge3J9CmZpZzExZC5jbHVzdGVyIDwtIGZpZzExZCR0cmVlX2NvbAoKZmlnMTFkLmNsdXN0ZXIucGxvdCA8LSBwbG90KGZpZzExZC5jbHVzdGVyLCBoYW5nID0gLTEsIGNleD0wLjYsIGF4ZXM9RkFMU0UsIGFubj1GQUxTRSkKCmZpZzExZC5jdXQgPC0gY3V0cmVlKGZpZzExZC5jbHVzdGVyLCAzKQpgYGAKYGBge3J9CmZpZzExZC5jdXRfZ2luaSA8LSBtZXJnZShwaGVub0NsaW5fZ2luaTMubm9ybTJbIShyb3duYW1lcyhwaGVub0NsaW5fZ2luaTMubm9ybTIpID09ICJMNDY0VCIpLGMoMSxncmVwKCJzdF8iLCBjb2xuYW1lcyhwaGVub0NsaW5fZ2luaTMubm9ybTJbLGMoMToxNCldKSkpXSwKICAgICAgICAgICAgICAgICAgICAgICAgIGZpZzExZC5jdXQsIGJ5ID0gInJvdy5uYW1lcyIsIGFsbC55ID0gVFJVRSkKZmlnMTFkLmN1dF9naW5pIDwtIGFzLmRhdGEuZnJhbWUoZmlnMTFkLmN1dF9naW5pLCByb3cubmFtZXMgPSBmaWcxMWQuY3V0X2dpbmkkUm93Lm5hbWVzKQpmaWcxMWQuY3V0X2dpbmkkUm93Lm5hbWVzIDwtIE5VTEwKY29sbmFtZXMoZmlnMTFkLmN1dF9naW5pKVtjb2xuYW1lcyhmaWcxMWQuY3V0X2dpbmkpID09ICJ5Il0gPC0gIkN1dEdyb3VwIgpmaWcxMWQuY3V0X2dpbmkkQ3V0R3JvdXAgPSBmYWN0b3IoZmlnMTFkLmN1dF9naW5pJEN1dEdyb3VwKQpgYGAKCmBgYHtyfQpmaWcxMWQuY3V0X2dpbmkubWVsdCA8LSBtZWx0KGZpZzExZC5jdXRfZ2luaSwgbmEucm0gPSBGKQoKZ2dwbG90KGZpZzExZC5jdXRfZ2luaS5tZWx0LCBhZXMoeCA9IHZhcmlhYmxlLCB5ID0gdmFsdWUsIGZpbGw9Q3V0R3JvdXApKSArCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3VyID0gImJsYWNrIiwgb3V0bGllci5zaGFwZSA9IDE2LCBvdXRsaWVyLnNpemUgPSAyLCBjb2xvdXIgPSAiYmxhY2siLCBub3RjaCA9IEZBTFNFKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICAjY29vcmRfZmxpcCgpICsKICBzY2FsZV9maWxsX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTEpICsKICBsYWJzKHggPSAiVCBjZWxsIHBoZW5vdHlwZSIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpCiAgI3N0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBOVUxMKQpgYGAKCmBgYHtyfQojIFJhdyBzdGFja2luZyBjaGFuZ2Ugb2YgdW5ub3JtYWxpemVkIGRhdGEgKEdpbmkgaGlnaCBncm91cCkKZ2dwbG90KHBoZW5vQ2xpbl9naW5pMy5tZWx0W3BoZW5vQ2xpbl9naW5pMy5tZWx0JEdpbmlJbmRleCA+PSAwLjI1NDMxLF0sIGFlcyh4ID0gR2luaUluZGV4LCB5ID0gdmFsdWUsZmlsbD12YXJpYWJsZSkpICsKICAgIGdlb21fYXJlYShwb3NpdGlvbiA9ICJzdGFjayIpICsKICAgIHRoZW1lX2NsYXNzaWMoKSArCiAgICAjY29vcmRfZmxpcCgpICsKICAgIHNjYWxlX2NvbG9yX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTAuOCkgKwogICAgc2NhbGVfZmlsbF9ucGcocGFsZXR0ZSA9IGMoIm5yYyIpLCBhbHBoYT0wLjgpICsKICAgIGxhYnMoeCA9ICJHaW5pIGNvZWZmaWNpZW50IikgKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIiksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MjApKQoKIyBTbW9vdGhlZCBzdGFja2luZyBjaGFuZ2Ugb2YgdW5ub3JtYWxpemVkIGRhdGEgKEdpbmkgaGlnaCBncm91cCkKZ2dwbG90KHBoZW5vQ2xpbl9naW5pMy5tZWx0W3BoZW5vQ2xpbl9naW5pMy5tZWx0JEdpbmlJbmRleCA+PSAwLjI1NDMxLF0sIGFlcyh4ID0gR2luaUluZGV4LCB5ID0gdmFsdWUpKSArCiAgICBzdGF0X3Ntb290aChhZXMoY29sb3I9dmFyaWFibGUsZmlsbD12YXJpYWJsZSksIG1ldGhvZCA9ICJsb2VzcyIsIGdlb209ImFyZWEiLCBwb3NpdGlvbiA9ICJzdGFjayIsc3BhbiA9IDAuMykgKwogICAgdGhlbWVfY2xhc3NpYygpICsKICAgICNjb29yZF9mbGlwKCkgKwogICAgc2NhbGVfY29sb3JfbnBnKHBhbGV0dGUgPSBjKCJucmMiKSwgYWxwaGE9MSkgKwogICAgc2NhbGVfZmlsbF9ucGcocGFsZXR0ZSA9IGMoIm5yYyIpLCBhbHBoYT0wLjcpICsKICAgIGxhYnMoeCA9ICJHaW5pIGNvZWZmaWNpZW50IikgKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIiksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MjApKQoKIyBSYXcgZnJhY3Rpb24gY2hhbmdlIG9mIHVubm9ybWFsaXplZCBkYXRhIChHaW5pIGhpZ2ggZ3JvdXApCmdncGxvdChwaGVub0NsaW5fZ2luaTMubWVsdFtwaGVub0NsaW5fZ2luaTMubWVsdCRHaW5pSW5kZXggPj0gMC4yNTQzMSxdLCBhZXMoeCA9IEdpbmlJbmRleCwgeSA9IHZhbHVlLGZpbGw9dmFyaWFibGUpKSArCiAgICBnZW9tX2FyZWEocG9zaXRpb24gPSAiZmlsbCIpICsKICAgIHRoZW1lX2NsYXNzaWMoKSArCiAgICAjY29vcmRfZmxpcCgpICsKICAgIHNjYWxlX2NvbG9yX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTAuOCkgKwogICAgc2NhbGVfZmlsbF9ucGcocGFsZXR0ZSA9IGMoIm5yYyIpLCBhbHBoYT0wLjgpICsKICAgIGxhYnMoeCA9ICJHaW5pIGNvZWZmaWNpZW50IikgKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3VyID0gImJsYWNrIiksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MjApKQoKIyBTbW9vdGhlZCBmcmFjdGlvbiBjaGFuZ2Ugb2YgdW5ub3JtYWxpemVkIGRhdGEgKEdpbmkgaGlnaCBncm91cCkKZ2dwbG90KHBoZW5vQ2xpbl9naW5pMy5tZWx0W3BoZW5vQ2xpbl9naW5pMy5tZWx0JEdpbmlJbmRleCA+PSAwLjI1NDMxLF0sIGFlcyh4ID0gR2luaUluZGV4LCB5ID0gdmFsdWUpKSArCiAgICBzdGF0X3Ntb290aChhZXMoY29sb3I9dmFyaWFibGUsZmlsbD12YXJpYWJsZSksIG1ldGhvZCA9ICJsb2VzcyIsIGdlb209ImFyZWEiLCBwb3NpdGlvbiA9ICJmaWxsIixzcGFuID0gMC4zKSArCiAgICB0aGVtZV9jbGFzc2ljKCkgKwogICAgI2Nvb3JkX2ZsaXAoKSArCiAgICBzY2FsZV9jb2xvcl9ucGcocGFsZXR0ZSA9IGMoIm5yYyIpLCBhbHBoYT0xKSArCiAgICBzY2FsZV9maWxsX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTAuNykgKwogICAgbGFicyh4ID0gIkdpbmkgY29lZmZpY2llbnQiKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpCgojIFJhdyBzdGFja2luZyB2YWx1ZSAoR2luaSBoaWdoIGdyb3VwKQpnZ3Bsb3QoZmlnMTFjLmN1dF9naW5pLm1lbHQyW2ZpZzExYy5jdXRfZ2luaS5tZWx0MiRHaW5pSW5kZXggPj0gMC4yNTQzMSxdLCBhZXMoeCA9IEdpbmlJbmRleCwgeSA9IHZhbHVlLGZpbGw9dmFyaWFibGUpKSArCiAgZ2VvbV9hcmVhKCkgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgI2Nvb3JkX2ZsaXAoKSArCiAgc2NhbGVfY29sb3JfbnBnKHBhbGV0dGUgPSBjKCJucmMiKSwgYWxwaGE9MSkgKwogIHNjYWxlX2ZpbGxfbnBnKHBhbGV0dGUgPSBjKCJucmMiKSwgYWxwaGE9MSkgKwogIGxhYnMoeCA9ICJHaW5pIGNvZWZmaWNpZW50IikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkKCiMgUmF3IGZyYWN0aW9uIHZhbHVlIChHaW5pIGhpZ2ggZ3JvdXApCmdncGxvdChmaWcxMWMuY3V0X2dpbmkubWVsdDJbZmlnMTFjLmN1dF9naW5pLm1lbHQyJEdpbmlJbmRleCA+PSAwLjI1NDMxLF0sIGFlcyh4ID0gR2luaUluZGV4LCB5ID0gdmFsdWUsZmlsbD12YXJpYWJsZSkpICsKICAgIGdlb21fYXJlYShwb3NpdGlvbiA9ICJmaWxsIikgKwogICAgdGhlbWVfY2xhc3NpYygpICsKICAgICNjb29yZF9mbGlwKCkgKwogICAgc2NhbGVfY29sb3JfbnBnKHBhbGV0dGUgPSBjKCJucmMiKSwgYWxwaGE9MC44KSArCiAgICBzY2FsZV9maWxsX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTAuOCkgKwogICAgbGFicyh4ID0gIkdpbmkgY29lZmZpY2llbnQiKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpCgojIFNtb290aGVkIHN0YWNraW5nIGNoYW5nZSAoR2luaSBoaWdoIGdyb3VwKQpnZ3Bsb3QoZmlnMTFjLmN1dF9naW5pLm1lbHQyW2ZpZzExYy5jdXRfZ2luaS5tZWx0MiRHaW5pSW5kZXggPj0gMC4yNTQzMSxdLCBhZXMoeCA9IEdpbmlJbmRleCwgeSA9IHZhbHVlKSkgKwogICAgc3RhdF9zbW9vdGgoYWVzKGNvbG9yPXZhcmlhYmxlLGZpbGw9dmFyaWFibGUpLCBtZXRob2QgPSAibG9lc3MiLCBnZW9tPSJhcmVhIiwgcG9zaXRpb24gPSAic3RhY2siLHNwYW4gPSAwLjUpICsKICAgIHRoZW1lX2NsYXNzaWMoKSArCiAgICAjY29vcmRfZmxpcCgpICsKICAgIHNjYWxlX2NvbG9yX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTEpICsKICAgIHNjYWxlX2ZpbGxfbnBnKHBhbGV0dGUgPSBjKCJucmMiKSwgYWxwaGE9MC43KSArCiAgICBsYWJzKHggPSAiR2luaSBjb2VmZmljaWVudCIpICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkKCiMgU21vb3RoZWQgZnJhY3Rpb24gY2hhbmdlIChHaW5pIGhpZ2ggZ3JvdXApCmdncGxvdChmaWcxMWMuY3V0X2dpbmkubWVsdDJbZmlnMTFjLmN1dF9naW5pLm1lbHQyJEdpbmlJbmRleCA+PSAwLjI1NDMxLF0sIGFlcyh4ID0gR2luaUluZGV4LCB5ID0gdmFsdWUpKSArCiAgICBzdGF0X3Ntb290aChhZXMoY29sb3I9dmFyaWFibGUsZmlsbD12YXJpYWJsZSksIG1ldGhvZCA9ICJsb2VzcyIsIGdlb209ImFyZWEiLCBwb3NpdGlvbiA9ICJmaWxsIixzcGFuID0gMC41KSArCiAgICB0aGVtZV9jbGFzc2ljKCkgKwogICAgI2Nvb3JkX2ZsaXAoKSArCiAgICBzY2FsZV9jb2xvcl9ucGcocGFsZXR0ZSA9IGMoIm5yYyIpLCBhbHBoYT0xKSArCiAgICBzY2FsZV9maWxsX25wZyhwYWxldHRlID0gYygibnJjIiksIGFscGhhPTAuNykgKwogICAgbGFicyh4ID0gIkdpbmkgY29lZmZpY2llbnQiKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIixheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCkpCgoKYGBgCgoKIyBGaWcxMgpgYGB7cn0KUGhlbm9BbGwgPC0gcmVhZF9leGNlbCgifi9Qcm9qZWN0L0JPTUkyL2JvbWkyX3BoZW5vdHlwZWRfZGVuc2l0aWVzX3NlcC54bHN4Iiwgc2hlZXQgPSAiQWxsIikKUGhlbm9BbGxOb0NLIDwtIHJlYWRfZXhjZWwoIn4vUHJvamVjdC9CT01JMi9ib21pMl9waGVub3R5cGVkX2RlbnNpdGllc19zZXAueGxzeCIsIHNoZWV0ID0gIm5vQ0siKQpQaGVub1RJTCA8LSByZWFkX2V4Y2VsKCJ+L1Byb2plY3QvQk9NSTIvYm9taTJfcGhlbm90eXBlZF9kZW5zaXRpZXNfc2VwLnhsc3giLCBzaGVldCA9ICJUSUwiKQpQaGVub05LIDwtIHJlYWRfZXhjZWwoIn4vUHJvamVjdC9CT01JMi9ib21pMl9waGVub3R5cGVkX2RlbnNpdGllc19zZXAueGxzeCIsIHNoZWV0ID0gIk5LIikKUGhlbm9BUEMgPC0gcmVhZF9leGNlbCgifi9Qcm9qZWN0L0JPTUkyL2JvbWkyX3BoZW5vdHlwZWRfZGVuc2l0aWVzX3NlcC54bHN4Iiwgc2hlZXQgPSAiQVBDIikKClBoZW5vQWxsIDwtIGFzLmRhdGEuZnJhbWUoUGhlbm9BbGwpClBoZW5vQWxsTm9DSyA8LSBhcy5kYXRhLmZyYW1lKFBoZW5vQWxsTm9DSykKUGhlbm9USUwgPC0gYXMuZGF0YS5mcmFtZShQaGVub1RJTCkKUGhlbm9OSyA8LSBhcy5kYXRhLmZyYW1lKFBoZW5vTkspClBoZW5vQVBDIDwtIGFzLmRhdGEuZnJhbWUoUGhlbm9BUEMpCgpQaGVub0FsbCRMb2NhdGlvbiA8LSBmYWN0b3IoUGhlbm9BbGwkTG9jYXRpb24sIGxldmVscyA9IGMoIlR1bW9yIiwgIlN0cm9tYSIsICJTQW5kVCIpKQpQaGVub0FsbE5vQ0skTG9jYXRpb24gPC0gZmFjdG9yKFBoZW5vQWxsTm9DSyRMb2NhdGlvbiwgbGV2ZWxzID0gYygiVHVtb3IiLCAiU3Ryb21hIiwgIlNBbmRUIikpClBoZW5vVElMJExvY2F0aW9uIDwtIGZhY3RvcihQaGVub1RJTCRMb2NhdGlvbiwgbGV2ZWxzID0gYygiVHVtb3IiLCAiU3Ryb21hIiwgIlNBbmRUIikpClBoZW5vTkskTG9jYXRpb24gPC0gZmFjdG9yKFBoZW5vTkskTG9jYXRpb24sIGxldmVscyA9IGMoIlR1bW9yIiwgIlN0cm9tYSIsICJTQW5kVCIpKQpQaGVub0FQQyRMb2NhdGlvbiA8LSBmYWN0b3IoUGhlbm9BUEMkTG9jYXRpb24sIGxldmVscyA9IGMoIlR1bW9yIiwgIlN0cm9tYSIsICJTQW5kVCIpKQoKUGhlbm9BbGwkUGhlbm9UeXBlIDwtIGZhY3RvcihQaGVub0FsbCRQaGVub1R5cGUsIGxldmVscyA9IGMoIkNENF9FZmYiLCJDRDRfVHJlZyIsIkNEOF9FZmYiLCJDRDhfVHJlZyIsIkJfY2VsbHMiLCJOS19jZWxscyIsIk5LVF9jZWxscyIsIk0xIiwiTTIiLCJDRDE2MyIsImlEQyIsIm1EQyIsInBEQyIsIlBhbkNLc2luZ2xlX1RJTCIsICJQYW5DS3NpbmdsZV9OSyIsIlBhbkNLc2luZ2xlX0FQQyIpKQpQaGVub0FsbE5vQ0skUGhlbm9UeXBlIDwtIGZhY3RvcihQaGVub0FsbE5vQ0skUGhlbm9UeXBlLCBsZXZlbHMgPSBjKCJDRDRfRWZmIiwiQ0Q0X1RyZWciLCJDRDhfRWZmIiwiQ0Q4X1RyZWciLCJCX2NlbGxzIiwiTktfY2VsbHMiLCJOS1RfY2VsbHMiLCJNMSIsIk0yIiwiQ0QxNjMiLCJpREMiLCJtREMiLCJwREMiKSkKUGhlbm9USUwkUGhlbm9UeXBlIDwtIGZhY3RvcihQaGVub1RJTCRQaGVub1R5cGUsIGxldmVscyA9IGMoIkNENF9FZmYiLCJDRDRfVHJlZyIsIkNEOF9FZmYiLCJDRDhfVHJlZyIsIkJfY2VsbHMiLCJQYW5DS3NpbmdsZV9USUwiKSkKUGhlbm9OSyRQaGVub1R5cGUgPC0gZmFjdG9yKFBoZW5vTkskUGhlbm9UeXBlLCBsZXZlbHMgPSBjKCJOS19jZWxscyIsIk5LVF9jZWxscyIsIk0xIiwiTTIiLCJDRDE2MyIsIlBhbkNLc2luZ2xlX05LIikpClBoZW5vQVBDJFBoZW5vVHlwZSA8LSBmYWN0b3IoUGhlbm9BUEMkUGhlbm9UeXBlLCBsZXZlbHMgPSBjKCJpREMiLCJtREMiLCJwREMiLCJQYW5DS3NpbmdsZV9BUEMiKSkKCmBgYAoKYGBge3J9CmZpZzEyYSA8LSBnZ3Bsb3QoUGhlbm9BbGxOb0NLLCBhZXMoeCA9IFBoZW5vVHlwZSwgeSA9IHZhbHVlLCBmaWxsPWdpbmlHcm91cCkpICsKICAgIGdlb21fYm94cGxvdChvdXRsaWVyLnNoYXBlID0gMTYsIG91dGxpZXIuc2l6ZSA9IDIsICkgKwogICAgdGhlbWVfY2xhc3NpYygpICsKICAgICMgY29vcmRfZmxpcCgpICsKICAgICMgc2NhbGVfZmlsbF9ucGcoKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBOVUxMLCBzaXplPTIpICsKICAgIGZhY2V0X3dyYXAofkxvY2F0aW9uLCBucm93ID0gMywgc3RyaXAucG9zaXRpb24gPSAibGVmdCIsIHNjYWxlPSJmcmVlIikgKwogICAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSkKCgpmaWcxMmIgPC0gZ2dwbG90KFBoZW5vQWxsTm9DSywgYWVzKHggPSBMb2NhdGlvbiwgeSA9IHZhbHVlLCBmaWxsPWdpbmlHcm91cCkpICsKICAgIGdlb21fYm94cGxvdChvdXRsaWVyLnNoYXBlID0gMTYsIG91dGxpZXIuc2l6ZSA9IDIsICkgKwogICAgdGhlbWVfY2xhc3NpYygpICsKICAgICMgY29vcmRfZmxpcCgpICsKICAgICMgc2NhbGVfZmlsbF9ucGcoKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICAgIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBOVUxMLCBzaXplPTEuNSkgKwogICAgZmFjZXRfd3JhcCh+UGhlbm9UeXBlLCBucm93ID0gMywgc3RyaXAucG9zaXRpb24gPSAibGVmdCIsIHNjYWxlPSJmcmVlIikKCmBgYAoKCgojIEZpZzEzIERpc3RhbmNlIGRhdGEKYGBge3J9CkRpc3RUSUwgPC0gcmVhZF9leGNlbCgifi9Qcm9qZWN0L1RDUi9EaXN0YW5jZS9CT01JMl9kaXN0Lnhsc3giLCBzaGVldCA9ICJUSUxfR2luaSIpCkRpc3RUSUwgPC0gYXMuZGF0YS5mcmFtZShEaXN0VElMKQpUSUxfY29yclQgPC0gcmNvcnIoYXMubWF0cml4KERpc3RUSUxbLGMoNSwyNzo1NildKSwgdHlwZSA9ICJzcGVhcm1hbiIpCndyaXRlLmNzdihUSUxfY29yclQkciwgZmlsZSA9ICJ+L1Byb2plY3QvVENSL0Rpc3RhbmNlL1RJTF9jb3JyLmNzdiIpCndyaXRlLmNzdihUSUxfY29yclQkUCwgZmlsZSA9ICJ+L1Byb2plY3QvVENSL0Rpc3RhbmNlL1RJTF9jb3JyX1B2YWx1ZS5jc3YiKQoKIyBtZWx0ClRJTF9jb3JyX21lbHQgPC0gcmVhZF9leGNlbCgifi9Qcm9qZWN0L1RDUi9EaXN0YW5jZS9CT01JMl9kaXN0Lnhsc3giLCBzaGVldCA9ICJUSUxfQ29yciIpClRJTF9jb3JyX21lbHRbLCJQX2FkanVzdCJdIDwtIHAuYWRqdXN0KFRJTF9jb3JyX21lbHQkYFAtVmFsdWVgLG1ldGhvZCA9ICJCSCIpClRJTF9jb3JyX21lbHQkbGFiZWwgPC0gTlVMTApUSUxfY29ycl9tZWx0LjFkW1RJTF9jb3JyX21lbHQuMWQkdmFyMV0KVElMX2NvcnJfbWVsdFtUSUxfY29ycl9tZWx0JFBfYWRqdXN0IDw9IDAuMDAxLCJsYWJlbCJdIDwtICIqKioiClRJTF9jb3JyX21lbHRbVElMX2NvcnJfbWVsdCRQX2FkanVzdCA+IDAuMDAxICYgVElMX2NvcnJfbWVsdCRQX2FkanVzdCA8PSAwLjAxLCJsYWJlbCJdIDwtICIqKiIKVElMX2NvcnJfbWVsdFtUSUxfY29ycl9tZWx0JFBfYWRqdXN0ID4gMC4wMSAmIFRJTF9jb3JyX21lbHQkUF9hZGp1c3QgPD0gMC4wNSwibGFiZWwiXSA8LSAiKiIKVElMX2NvcnJfbWVsdCRDb3JyZWxhdGlvbgpgYGAKCmBgYHtyfQpnZ3Bsb3QoVElMX2NvcnJfbWVsdCwgYWVzKHZhcjEsIHZhcjIsIGZpbGwgPSBDb3JyZWxhdGlvbikpICsKICAgIGdlb21fcG9pbnQoc2hhcGU9MjEsIGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAxMikrCiAgICB0aGVtZV9jbGFzc2ljKCkrCiAgICBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvdXJzID0gcmV2KGJyZXdlci5wYWwoNSwgIlNwZWN0cmFsIikpKSsKICAgIGxhYnModGl0bGUgPSAiQ29ycmVsYXRpb24iLCB4ID0gIk91dHNldCIsIHkgPSAiRW5kIikgKwogICAgdGhlbWUoYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIiksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTUpKSsKICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBsYWJlbCksIHNpemUgPSA1LCBjb2xvdXIgPSAiYmxhY2siKQpgYGAKCiMjIDFEIHBsb3QKYGBge3J9ClRJTF9jb3JyX21lbHQuMWQgPC0gcmVhZF9leGNlbCgifi9Qcm9qZWN0L1RDUl9TdW1tYXJ5L1dyaXRpbmcvU3VtU3VwLnhsc3giLCBzaGVldCA9ICJUSUxfQ29ycl8xRCIpClRJTF9jb3JyX21lbHQuMWQgPC0gYXMuZGF0YS5mcmFtZShUSUxfY29ycl9tZWx0LjFkKQojIC0wLjEyMjQxOTM2NQkwLjEzODI3Mzk5MwojVElMX2NvcnJfbWVsdC4xZFtUSUxfY29ycl9tZWx0LjFkJHZhcjEgPT0gIkNENF9UcmVnIiAmIFRJTF9jb3JyX21lbHQuMWQkdmFyMiA9PSAiUGFuQ0tzaW5nbGUiLCBjKCJDb3JyZWxhdGlvbiIsIlAtVmFsdWUiKV0gPC0gYygtMC4xMjI0MTkzNjUsIDAuMTM4MjczOTkzKQpUSUxfY29ycl9tZWx0LjFkWywiUF9hZGp1c3QiXSA8LSBwLmFkanVzdChUSUxfY29ycl9tZWx0LjFkJGBQLVZhbHVlYCxtZXRob2QgPSAiQkgiKQpUSUxfY29ycl9tZWx0LjFkW1RJTF9jb3JyX21lbHQuMWQkUF9hZGp1c3QgPD0gMC4wMDEsImxhYmVsIl0gPC0gIioqKiIKVElMX2NvcnJfbWVsdC4xZFtUSUxfY29ycl9tZWx0LjFkJFBfYWRqdXN0ID4gMC4wMDEgJiBUSUxfY29ycl9tZWx0LjFkJFBfYWRqdXN0IDw9IDAuMDEsImxhYmVsIl0gPC0gIioqIgpUSUxfY29ycl9tZWx0LjFkW1RJTF9jb3JyX21lbHQuMWQkUF9hZGp1c3QgPiAwLjAxICYgVElMX2NvcnJfbWVsdC4xZCRQX2FkanVzdCA8PSAwLjA1LCJsYWJlbCJdIDwtICIqIgpgYGAKCmBgYHtyfQpnZ3Bsb3QoVElMX2NvcnJfbWVsdC4xZCwgYWVzKHZhcjIsIHZhcjEsIGZpbGwgPSBDb3JyZWxhdGlvbikpICsKICAgIGdlb21fcG9pbnQoc2hhcGU9MjEsIGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAxMikrCiAgICB0aGVtZV9jbGFzc2ljKCkrCiAgICBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvdXJzID0gcmV2KGJyZXdlci5wYWwoNSwgIlNwZWN0cmFsIikpKSsKICAgIGxhYnModGl0bGUgPSAiQ29ycmVsYXRpb24iLCB4ID0gIk91dHNldCIsIHkgPSAiRW5kIikgKwogICAgdGhlbWUoYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIiksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTUpKSsKICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBsYWJlbCksIHNpemUgPSA1LCBjb2xvdXIgPSAiYmxhY2siKQpgYGAKCgoKCiMgRmlnMTQgaW1tdW5ldGhlcmFweSB0cmVhdGVkIGNvaG9ydApgYGB7cn0KbGlicmFyeShyZWFkeGwpCml0Q29ob3J0IDwtIHJlYWRfZXhjZWwoIn4vUHJvamVjdC9UQ1IvSW1tdW5lQ29ob3J0L0dTRTEyNjA0NF9naW5pX2FiLnhsc3giLCAKICAgIHNoZWV0ID0gIlNoZWV0MyIpClZpZXcoaXRDb2hvcnQpCgppdENvaG9ydCA8LSBhcy5kYXRhLmZyYW1lKGl0Q29ob3J0KQpgYGAKCmBgYHtyfQpmMTRhIDwtIGdncGxvdChpdENvaG9ydCwgYWVzKHggPSBmYWN0b3IoUmVzcG9uc2l2ZW5lc3MsIGxldmVsPWMoJ1Jlc3BvbmRlcicsJ05vbi1yZXNwb25kZXInICkpLCB5ID0gR2luaSwgZmlsbD1SZXNwb25zaXZlbmVzcykpICsKICBnZW9tX2JveHBsb3Qob3V0bGllci5jb2xvdXIgPSAiYmxhY2siLCBvdXRsaWVyLnNoYXBlID0gMTYsIG91dGxpZXIuc2l6ZSA9IDIsIGNvbG91ciA9ICJibGFjayIsIG5vdGNoID0gRkFMU0UpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogICNjb29yZF9mbGlwKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiMwMEJGQzQiLCAiI0Y4NzY2RCIpKSArCiAgbGFicyh0aXRsZSA9ICJSZXNwb25zaXZlbmVzcyIsIHggPSAiUmVzcG9uc2l2ZW5lc3MiLCB5ID0gIkdpbmkgY29lZmZpY2llbnQiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBOVUxMKQoKZjE0YQpgYGAKCmBgYHtyfQpjb2xuYW1lcyhpdENvaG9ydClbY29sbmFtZXMoaXRDb2hvcnQpID09ICJQcm9ncmVzc2lvbiBmcmVlIHN1cnZpdmFsIFxyXG4obW9udGgpIl0gPSAiUHJvZ3Jlc3Npb24gZnJlZSBzdXJ2aXZhbCAobW9udGgpIgojIFVzZSB0aGUgY3V0IG9mZiBmcm9tIG91ciBkYXRhc2V0Cml0Q29ob3J0W2l0Q29ob3J0JEdpbmkgPj0gMC4xOSwgImdpbmlHcm91cCJdIDwtICJIaWdoIgppdENvaG9ydFtpdENvaG9ydCRHaW5pIDwgMC4xOSwgImdpbmlHcm91cCJdIDwtICJMb3ciCml0Q29ob3J0JGdpbmlHcm91cCA9IGZhY3RvcihpdENvaG9ydCRnaW5pR3JvdXAsIGxldmVscyA9IGMoIkhpZ2giLCAiTG93IikpCgojIGNvbnN0cnVjdCB0aGUgb2JqZWN0CmZpZzE0Yl90ZXN0IDwtIHN1cnZmaXQoU3VydihgUHJvZ3Jlc3Npb24gZnJlZSBzdXJ2aXZhbCAobW9udGgpYCwgU3RhdHVzKSB+IGdpbmlHcm91cCwgZGF0YSA9IGl0Q29ob3J0KQoKcHJpbnQoZmlnMTRiX3Rlc3QpCgpzdW1tYXJ5KGZpZzE0Yl90ZXN0KSR0YWJsZQpgYGAKCmBgYHtyfQpmaWcxNGIgPC0gZ2dzdXJ2cGxvdChmaWcxNGJfdGVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgcHZhbCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjZTY0YjM1IiwgIiM0ZGJiZDUiKSwKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsudGltZS5ieSA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9jbGFzc2ljKCksCiAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC5sYWJzID0gYygiSGlnaCIsICJMb3ciKSwKICAgICAgICAgICAgICAgICAgICAgICAgcmlzay50YWJsZSA9ICJhYnNfcGN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgcmlzay50YWJsZS55LnRleHQgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgeGxhYiA9ICJUaW1lIChtb250aHMpIiwKICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiZ2luaVN1cnYiLAogICAgICAgICAgICAgICAgICAgICAgICB4bGltID0gYygwLDE0LjUpLAogICAgICAgICAgICAgICAgICAgICAgICBheGVzLm9mZnNldCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICByaXNrLnRhYmxlLmZvbnRzaXplID0gMi41LAogICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQgPSBjKDAuOTUsMC45NyksCiAgICAgICAgICAgICAgICAgICAgICAgIHJpc2sudGFibGUudGl0bGUgPSAiTnVtYmVyIGF0IHJpc2sgYnkgdGltZTogbiAoJSkiLAogICAgICAgICAgICAgICAgICAgICAgICBmb250Lm1haW4gPSBjKCksCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrLnguYnk9MwogICAgICAgICAgICAgICAgICAgICApCgoKZmlnMTRiCmBgYAoKYGBge3J9CnN1cnZfbWVkaWFuKGZpZzE0Yl90ZXN0KQpgYGAKCgojIEZpZ3VyZSAxNSBMeW1waCBub2RlcwpgYGB7cn0KbGlicmFyeShzdHJpbmdyKQpHaW5pQ2xpbl90dW1vciRseW1waCA8LSBzdHJfc3ViKEdpbmlDbGluX3R1bW9yJGBwVE5NIGVkdCA4IChQTUkpYCwgLTIsLTEpCgpHaW5pQ2xpbl90dW1vcltHaW5pQ2xpbl90dW1vciRseW1waCA9PSAiTjAiLCAiTHltcGhfbm9kZSJdID0gIk4wIgpHaW5pQ2xpbl90dW1vcltHaW5pQ2xpbl90dW1vciRseW1waCA9PSAiTjEifCBHaW5pQ2xpbl90dW1vciRseW1waCA9PSAiTjIiLCAiTHltcGhfbm9kZSJdID0gIk4xL04yIgoKZ2dwbG90KEdpbmlDbGluX3R1bW9yLCBhZXMoeCA9IEx5bXBoX25vZGUsIHkgPSBHaW5pSW5kZXgsIGZpbGw9THltcGhfbm9kZSkpICsKICBnZW9tX2JveHBsb3Qob3V0bGllci5jb2xvdXIgPSAiYmxhY2siLCBvdXRsaWVyLnNoYXBlID0gMTYsIG91dGxpZXIuc2l6ZSA9IDIsIGNvbG91ciA9ICJibGFjayIsIG5vdGNoID0gRkFMU0UpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogICNjb29yZF9mbGlwKCkgKwogICNzY2FsZV9jb2xvcl9ucGcoKSArCiAgbGFicyh0aXRsZSA9ICJseW1waCIsIHggPSAibHltcGgiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBOVUxMKQpgYGAKCiMgQmV0YSBjbG9uZSBkaXN0YW5jZQpgYGB7cn0KR2luaURpc3QgPC0gcmVhZC50YWJsZSgiL1VzZXJzL2h1aXl1ODE4L1Byb2plY3QvVENSL1RDUmRpc3QvL2Nsb25lU3VtbWFyeS9iZXRhX3R1bW9yX2Rpc3RfcmFuay50eHQiKQpHaW5pRGlzdCA8LSBhcy5kYXRhLmZyYW1lKEdpbmlEaXN0KQpgYGAKCmBgYHtyfQpwaGVhdG1hcChHaW5pRGlzdCwKICAgICAgICAgY2x1c3Rlcl9yb3dzID0gRiwgY2x1c3Rlcl9jb2xzID0gRiwKICAgICAgICAgI2N1dHJlZV9jb2xzID0gMywKICAgICAgICAgY29sb3IgPSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwobiA9IDcsIG5hbWUgPSAiUmRZbEJ1IikpKDEwMCksCiAgICAgICAgIGZvbnRzaXplID0gNSwKICAgICAgICAgc2hvd19jb2xuYW1lcyA9IFQKKQpgYGAKCmBgYHtyfQojIExvYWQgdGhlIGFubm90YXRpb24KR2luaURpc3RfYW5ubyA8LSAgcmVhZF9leGNlbCgifi9Qcm9qZWN0L1RDUi9UQ1JkaXN0L2Nsb25lU3VtbWFyeS9iZXRhX3R1bW9yLnhsc3giLCBzaGVldCA9ICJEaXN0YW5jZV9ERl8yIikKR2luaURpc3RfYW5ubyA8LSBhcy5kYXRhLmZyYW1lKEdpbmlEaXN0X2Fubm8pCnJvd25hbWVzKEdpbmlEaXN0X2Fubm8pIDwtIEdpbmlEaXN0X2Fubm8kY2xvbmVfaWRfbmV3CmBgYAoKYGBge3J9CkdpbmlEaXN0X2Fubm9fY29sb3IgPSBsaXN0KAojICAiR2luaUluZGV4IiA9IGNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbChuID0gOSwgbmFtZSA9ICJSZWRzIikpKDEwMCksCiAgIkFudGlfdmlydXMiID0gYyhZID0gIiNENDVGNTEiLCBOID0gIiNCN0QyRTgiKSkKYGBgCgpgYGB7cn0KcGhlYXRtYXAoR2luaURpc3QsCiAgICAgICAgIGNsdXN0ZXJfcm93cyA9IEYsIGNsdXN0ZXJfY29scyA9IEYsCiAgICAgICAgIGNvbG9yID0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKG4gPSA3LCBuYW1lID0gIlJkWWxCdSIpKSgxMDApLAogICAgICAgICBhbm5vdGF0aW9uX2NvbCA9IEdpbmlEaXN0X2Fubm9bIkFudGlfdmlydXMiXSwKICAgICAgICAgYW5ub3RhdGlvbl9jb2xvcnMgPSBHaW5pRGlzdF9hbm5vX2NvbG9yLAogICAgICAgICBmb250c2l6ZSA9IDUsCiAgICAgICAgIHNob3dfY29sbmFtZXMgPSBUCiAgICAgICAgICkKYGBgCgpgYGB7cn0KcGhlYXRtYXAoR2luaURpc3QsCiAgICAgICAgIGNsdXN0ZXJpbmdfbWV0aG9kID0gIndhcmQuRDIiLAogICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX3Jvd3MgPSAiZXVjbGlkZWFuIiwgY2x1c3RlcmluZ19kaXN0YW5jZV9jb2xzID0gImV1Y2xpZGVhbiIsCiAgICAgICAgIGNvbG9yID0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKG4gPSA3LCBuYW1lID0gIlJkWWxCdSIpKSgxMDApLAogICAgICAgICBhbm5vdGF0aW9uX2NvbCA9IEdpbmlEaXN0X2Fubm9bIkFudGlfdmlydXMiXSwKICAgICAgICAgYW5ub3RhdGlvbl9jb2xvcnMgPSBHaW5pRGlzdF9hbm5vX2NvbG9yLAogICAgICAgICBmb250c2l6ZSA9IDUsCiAgICAgICAgIHNob3dfY29sbmFtZXMgPSBUCiAgICAgICAgICkKYGBgCgoKYGBge3J9CnBoZWF0bWFwKHQoaWhjSGVhdFRfdHVtb3Jfbm9ybTIpLCBjbHVzdGVyaW5nX21ldGhvZCA9ICJ3YXJkLkQyIiwKICAgICAgICAgICAgICAgICAgY2x1c3RlcmluZ19kaXN0YW5jZV9yb3dzID0gImV1Y2xpZGVhbiIsIGNsdXN0ZXJpbmdfZGlzdGFuY2VfY29scyA9ICJldWNsaWRlYW4iLAogICAgICAgICAgICAgICAgICBjdXRyZWVfY29scyA9IDMsCiAgICAgICAgICAgICAgICAgICNjb2xvciA9IGNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbChuID0gNywgbmFtZSA9ICJZbEduQnUiKSkoMTAwKSwKICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbl9jb2wgPSBpaGNBbm5vLAogICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uX2NvbG9ycyA9IGloY0Fubm9fY29sb3IsCiAgICAgICAgICAgICAgICAgIGZvbnRzaXplID0gNSwKICAgICAgICAgICAgICAgICAgc2hvd19jb2xuYW1lcyA9IEYKICAgICAgICAgICAgICAgICAgKQpgYGAKCgojIENhbmNlciB0ZXN0aXMgYW50aWdlbnMKYGBge3J9CkNUQV9saXN0IDwtIHJlYWRfZXhjZWwoIn4vUHJvamVjdC9UQ1JfU3VtbWFyeS9Xcml0aW5nL1N1bVN1cC54bHN4Iiwgc2hlZXQgPSAiQ1RBIikKCkNUQV9saXN0IDwtIGFzLmRhdGEuZnJhbWUoQ1RBX2xpc3QpCmBgYAoKYGBge3J9CkJvbWkyUkNfdHVtb3Jfbm9ybSA8LSByZWFkLmNzdigifi9Qcm9qZWN0L0NsaW5pY2FsL0JPTUkyL0JPTUkyX1JOQXNlcV9GUEtNL1JOQVNlcV9jb3VudHNfdHVtb3Jfbm9ybS50eHQiLCBzZXA9Ilx0IikKYGBgCgojIyBDVEEgbGlzdCAxIChhbGwgZnJvbSBkYXRhYmFzZSkKYGBge3J9CmxpYnJhcnkoZGF0YS50YWJsZSkKR2luaUNsaW5fQ1RBX29yaSA8LSBhcy5kYXRhLmZyYW1lKHQoQm9taTJSQ190dW1vcl9ub3JtW0NUQV9saXN0JEVuc2dpZF8xLF0pKQoKR2luaUNsaW5fQ1RBX29yaSA8LSBtZXJnZShHaW5pQ2xpbl90dW1vciwgR2luaUNsaW5fQ1RBX29yaSwgYnkueCA9ICJJRCIgLGJ5LnkgPSAicm93Lm5hbWVzIikKc2V0bmFtZXMoR2luaUNsaW5fQ1RBX29yaSwgb2xkID0gIENUQV9saXN0W1siRW5zZ2lkXzEiXV0sIG5ldyA9IENUQV9saXN0W1siR2VuZV8xIl1dKQpgYGAKCmBgYHtyfQpHaW5pQ2xpbl9DVEFfb3JpWzEsMzddCmBgYAoKYGBge3J9CkNUQV9jb3JyIDwtIHJjb3JyKGFzLm1hdHJpeChHaW5pQ2xpbl9DVEFfb3JpWyxjKDUsMzc6MTMyKV0pLCB0eXBlID0gInNwZWFybWFuIikKCndyaXRlLmNzdihDVEFfY29yciRyLCBmaWxlID0gIn4vUHJvamVjdC9UQ1IvQ1RBL2N0YUNvci5jc3YiKQp3cml0ZS5jc3YoQ1RBX2NvcnIkUCwgZmlsZSA9ICJ+L1Byb2plY3QvVENSL0NUQS9jdGFQdmFsdWUuY3N2IikKYGBgCgpgYGB7cn0KQ1RBX2NvcnJUIDwtIHJlYWRfZXhjZWwoIn4vUHJvamVjdC9UQ1IvQ1RBL0NUQS54bHN4Iiwgc2hlZXQgPSAiU2hlZXQzIikKCkNUQV9jb3JyVCA8LSBhcy5kYXRhLmZyYW1lKENUQV9jb3JyVCkKCkNUQV9jb3JyVCA8LSByZW5hbWUoQ1RBX2NvcnJULCBjKCJHZW5lU3ltYm9sIj0iLi4uMSIpKQpDVEFfY29yclRbLCJwYWRqIl0gPC0gcC5hZGp1c3QoQ1RBX2NvcnJUJGBQLXZhbHVlYCxtZXRob2QgPSAiQkgiKQoKd3JpdGUuY3N2KENUQV9jb3JyVCwgZmlsZSA9ICJ+L1Byb2plY3QvVENSL0NUQS9jdGFQYWRqLmNzdiIpCmBgYAoKYGBge3J9CkNUQV9jb3JyVFtDVEFfY29yclQkcGFkaiA8IDAuMDUsXQpgYGAKCiMjIENUQSBsaXN0IDIgKG5vdmFsIGxpc3QpCmBgYHtyfQpHaW5pQ2xpbl9DVEFfb3JpXzIgPC0gYXMuZGF0YS5mcmFtZSh0KEJvbWkyUkNfdHVtb3Jfbm9ybVtDVEFfbGlzdFshaXMubmEoQ1RBX2xpc3QkRW5zZ2lkXzIpLCJFbnNnaWRfMiJdLF0pKQoKR2luaUNsaW5fQ1RBX29yaV8yIDwtIG1lcmdlKEdpbmlDbGluX3R1bW9yLCBHaW5pQ2xpbl9DVEFfb3JpXzIsIGJ5LnggPSAiSUQiICxieS55ID0gInJvdy5uYW1lcyIpCnNldG5hbWVzKEdpbmlDbGluX0NUQV9vcmlfMiwgb2xkID0gIENUQV9saXN0WyFpcy5uYShDVEFfbGlzdCRFbnNnaWRfMiksIkVuc2dpZF8yIl0sIG5ldyA9IENUQV9saXN0WyFpcy5uYShDVEFfbGlzdCRFbnNnaWRfMiksIkdlbmVfMiJdKQpgYGAKCmBgYHtyfQpHaW5pQ2xpbl9DVEFfb3JpXzJbMywzN10KYGBgCgpgYGB7cn0KQ1RBX2NvcnJfMiA8LSByY29ycihhcy5tYXRyaXgoR2luaUNsaW5fQ1RBX29yaV8yWyxjKDUsMzc6MTI2KV0pLCB0eXBlID0gInNwZWFybWFuIikKCndyaXRlLmNzdihDVEFfY29ycl8yJHIsIGZpbGUgPSAifi9Qcm9qZWN0L1RDUi9DVEEvY3RhQ29yX2xpc3QyLmNzdiIpCndyaXRlLmNzdihDVEFfY29ycl8yJFAsIGZpbGUgPSAifi9Qcm9qZWN0L1RDUi9DVEEvY3RhUHZhbHVlX2xpc3QyLmNzdiIpCmBgYAoKYGBge3J9CkNUQV9jb3JyVF8yIDwtIHJlYWRfZXhjZWwoIn4vUHJvamVjdC9UQ1IvQ1RBL0NUQS54bHN4Iiwgc2hlZXQgPSAiR2VuZUxpc3QyIikKQ1RBX2NvcnJUXzIgPC0gYXMuZGF0YS5mcmFtZShDVEFfY29yclRfMikKCkNUQV9jb3JyVF8yWywicGFkaiJdIDwtIHAuYWRqdXN0KENUQV9jb3JyVF8yJFB2YWx1ZSxtZXRob2QgPSAiQkgiKQpgYGAKCgojIyBWb2Nhbm9sIHBsb3QKYGBge3J9CmdncGxvdChkYXRhID0gZGlmZkdlbmUsIGFlcyh4ID0gbG9nMkZvbGRDaGFuZ2UsIHkgPSAtbG9nMTAocGFkaiksIGNvbG9yID0gc2lnbikpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMSkgKyAgI0NyZWF0ZSBzY2F0dGVyIHBsb3QKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygncmVkJywgJ2dyYXknLCAnZ3JlZW4nKSwgbGltaXRzID0gYygnVVAnLCAnbm9uZScsICdET1dOJykpICsgICNTZXQgdGhlIGNvbG9yCiAgbGFicyh4ID0gJ2xvZzIgRm9sZCBDaGFuZ2UnLCB5ID0gJy1sb2cxMCBhZGp1c3QgcC12YWx1ZScsIHRpdGxlID0gJ0hpZ2ggY2xvbmFsaXR5IHZzIExvdyBjbG9uYWxpdHknLCBjb2xvciA9ICcnKSArICAjU2V0IHRoZSBsYWJlbHMKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBzaXplID0gMTQpLCBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCAjQ2hhbmdlIHRoZSB0aGVtIGFuZCBncmlkIGxpbmVzCiAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICdibGFjaycsIGZpbGwgPSAndHJhbnNwYXJlbnQnKSwgCiAgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsID0gJ3RyYW5zcGFyZW50JykpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjKC0xLCAxKSwgbHR5ID0gMywgY29sb3IgPSAnYmxhY2snKSArICAjQWRkIHRocmVzaG9sZCBsaW5lCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMiwgbHR5ID0gMywgY29sb3IgPSAnYmxhY2snKSArCiAgeGxpbSgtMTIsIDEyKSArIHlsaW0oMCwgMzUpICsgI1NldCB0aGUgY3VydmUgYm91bmRhcnkKICBnZW9tX3RleHRfcmVwZWwoCiAgICBkYXRhID0gZGlmZkdlbmUsCiAgICBhZXMobGFiZWwgPSBsYWJlbCksCiAgICBzaXplID0gMywgc2VnbWVudC5jb2xvciA9ICJibHVlIiwgc2hvdy5sZWduZWQgPSBGQUxTRSwKICAgIHBvaW50LnBhZGRpbmcgPSB1bml0KDAuOCwgImxpbmVzIikKICApCmBgYAoKCiMgSVNTIHBsb3QKYGBge3J9CklTU19kb3RfZGF0YSA8LSByZWFkX2V4Y2VsKCJ+L1Byb2plY3QvVENSL0lTU2ltbXVub3BhbmVscy9BbmFseXNpcy9Eb3RQbG90IHNhbXBsZS54bHN4IikKVmlldyhJU1NfZG90X2RhdGEpCgpJU1NfZG90X2RhdGEgPC0gYXMuZGF0YS5mcmFtZShJU1NfZG90X2RhdGEpCmBgYAoKYGBge3J9CmdncGxvdChJU1NfZG90X2RhdGEsIGFlcyhDbG9uZSwgRVBDQU1fQ0RIMV9hbm5vKSkgKwogIGdlb21fcG9pbnQoYWVzKHNpemU9Q2xvbmVfZnJhY3Rpb24sIGNvbG9yID0gQ2xvbmVfbWVhbikpKwogIGZhY2V0X3dyYXAofiBTYW1wbGUsIHNjYWxlcyA9ICJmcmVlX3giLCBkcm9wID0gVFJVRSkgKwogIHRoZW1lX2J3KCkrCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgICMgUmVtb3ZlIG1ham9yIGdyaWQgbGluZXMKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKSArICMgUmVtb3ZlIG1pbm9yIGdyaWQgbGluZXMKICBzY2FsZV9zaXplKHJhbmdlID0gYygxLCAxMCkpICsKICBzY2FsZV9jb2xvcl9ncmFkaWVudG4oY29sb3JzID0gcmV2KGJyZXdlci5wYWwoNSwgIlNwZWN0cmFsIikpKSsKICBsYWJzKHRpdGxlID0gIkJ1YmJsZSBwbG90IGdyb3VwZWQgYnkgc2FtcGxlIiwgeCA9ICJDbG9uZSIsIHkgPSAiRVBDQU1fQ0RIMSBhbm5vdGF0aW9uIikgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIiwgYW5nbGUgPSA0NSksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTUpKQogICNnZW9tX3RleHQoYWVzKGxhYmVsID0gbGFiZWwpLCBzaXplID0gNSwgY29sb3VyID0gImJsYWNrIikKYGBgCgpgYGB7cn0KbGlicmFyeShkcGx5cikKCklTU19kb3RfZGF0YSA8LSBJU1NfZG90X2RhdGEgJT4lCiAgZ3JvdXBfYnkoU2FtcGxlKSAlPiUKICBtdXRhdGUoTm9ybWFsaXplZF9DbG9uZV9mcmFjdGlvbiA9IHNjYWxlKENsb25lX2ZyYWN0aW9uKSwgICMgTm9ybWFsaXppbmcgY2xvbmUgZnJhY3Rpb24KICAgICAgICAgTm9ybWFsaXplZF9DbG9uZV9tZWFuID0gc2NhbGUoQ2xvbmVfbWVhbikpICU+JSAgIyBOb3JtYWxpemluZyBjbG9uZSBtZWFuCiAgdW5ncm91cCgpCmBgYAoKCmBgYHtyfQpJU1NfZG90X2RhdGFfTDc2NiA8LSBJU1NfZG90X2RhdGFbSVNTX2RvdF9kYXRhJFNhbXBsZSA9PSAiTDc2NlQiLF0KYGBgCgpgYGB7cn0KZ2dwbG90KElTU19kb3RfZGF0YV9MNzY2LCBhZXMoQ2xvbmUsIEVQQ0FNX0NESDFfYW5ubykpICsKICBnZW9tX3BvaW50KGFlcyhzaXplPUNsb25lX2ZyYWN0aW9uLCBjb2xvciA9IENsb25lX21lYW4pKSsKICB0aGVtZV9idygpKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksICAjIFJlbW92ZSBtYWpvciBncmlkIGxpbmVzCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSkgKyAjIFJlbW92ZSBtaW5vciBncmlkIGxpbmVzCiAgc2NhbGVfY29sb3JfZ3JhZGllbnRuKGNvbG9ycyA9IHJldihicmV3ZXIucGFsKDUsICJTcGVjdHJhbCIpKSkrCiAgbGFicyh0aXRsZSA9ICJCdWJibGUgcGxvdCBncm91cGVkIGJ5IHNhbXBsZSIsIHggPSAiQ2xvbmUiLCB5ID0gIkVQQ0FNX0NESDEgYW5ub3RhdGlvbiIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICJibGFjayIsIGFuZ2xlID0gNDUpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSkKYGBgCgpgYGB7cn0KSVNTX2RvdF9kYXRhX0w1OTYgPC0gSVNTX2RvdF9kYXRhW0lTU19kb3RfZGF0YSRTYW1wbGUgPT0gIkw1OTZUIixdCmBgYAoKYGBge3J9CmdncGxvdChJU1NfZG90X2RhdGFfTDU5NiwgYWVzKENsb25lLCBFUENBTV9DREgxX2Fubm8pKSArCiAgZ2VvbV9wb2ludChhZXMoc2l6ZT1DbG9uZV9mcmFjdGlvbiwgY29sb3IgPSBDbG9uZV9tZWFuKSkrCiAgdGhlbWVfYncoKSsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCAgIyBSZW1vdmUgbWFqb3IgZ3JpZCBsaW5lcwogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpICsgIyBSZW1vdmUgbWlub3IgZ3JpZCBsaW5lcwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvcnMgPSByZXYoYnJld2VyLnBhbCg1LCAiU3BlY3RyYWwiKSkpKwogIHNjYWxlX3NpemUocmFuZ2UgPSBjKDEsIDEwKSkgKwogIGxhYnModGl0bGUgPSAiQnViYmxlIHBsb3QgZ3JvdXBlZCBieSBzYW1wbGUiLCB4ID0gIkNsb25lIiwgeSA9ICJFUENBTV9DREgxIGFubm90YXRpb24iKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siLCBhbmdsZSA9IDQ1KSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSkpCmBgYAoKCgoKCgoKCgoK